package com.tudouji.project.bill.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.flow.service.mapper.IFileInfoMapper;
import com.flow.service.mapper.IFlowTaskMapper;
import com.flow.service.mapper.IFlowTempNodeMapper;
import com.flow.service.pojo.BasePojo;
import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.flow.FileInfo;
import com.flow.service.pojo.flow.FlowTempNode;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.IFlowBaseService;
import com.flow.service.process.service.impl.CallBackParameterWrapper;
import com.flow.service.process.service.impl.FlowProcessProxy;
import com.github.pagehelper.PageHelper;
import com.tudouji.common.constant.HttpStatus;
import com.tudouji.common.enums.WhoutformTypeEnums;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.UUIDCreate;
import com.tudouji.common.utils.sql.SqlUtil;
import com.tudouji.framework.task.BatchStatus;
import com.tudouji.framework.task.MeituanDataProcessUtil;
import com.tudouji.framework.task.PrebalanceTask;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.framework.web.page.PageDomain;
import com.tudouji.framework.web.page.TableSupport;
import com.tudouji.project.bill.domain.*;
import com.tudouji.project.bill.domain.vo.SellformListRep;
import com.tudouji.project.bill.domain.vo.SellformRep;
import com.tudouji.project.bill.mapper.DiscountMapper;
import com.tudouji.project.bill.mapper.SellformMapper;
import com.tudouji.project.bill.mapper.SellitemMapper;
import com.tudouji.project.bill.mapper.SellspitemMapper;
import com.tudouji.project.bill.service.IAutoTransferService;
import com.tudouji.project.bill.service.IRechargeService;
import com.tudouji.project.bill.service.ISellformService;
import com.tudouji.project.customer.domain.Customer;
import com.tudouji.project.customer.mapper.CustomerMapper;
import com.tudouji.project.customer.service.impl.ReceivableflowServiceImpl;
import com.tudouji.project.dept.domain.DeptStoreroom;
import com.tudouji.project.dept.mapper.DeptStoreroomMapper;
import com.tudouji.project.flow.service.impl.FlowtempnodeServiceImpl;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.harvest.domain.Freightorder;
import com.tudouji.project.harvest.service.IFreightorderService;
import com.tudouji.project.organization.domain.Organization;
import com.tudouji.project.organization.mapper.OrganizationMapper;
import com.tudouji.project.pay.domain.SfPrebalanceRecord;
import com.tudouji.project.pay.mapper.SfPrebalanceRecordMapper;
import com.tudouji.project.pay.service.impl.SfPrebalanceRecordServiceImpl;
import com.tudouji.project.permission.domain.Salespermission;
import com.tudouji.project.permission.service.impl.SalespermissionServiceImpl;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.domain.Suitpack;
import com.tudouji.project.product.mapper.SalesspecificationMapper;
import com.tudouji.project.product.mapper.SuitpackMapper;
import com.tudouji.project.product.service.impl.SuitpackServiceImpl;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.domain.Storeroom;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.store.mapper.StoreroomMapper;
import com.tudouji.project.system.domain.SysDept;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.mapper.SysDeptMapper;
import com.tudouji.project.system.service.ISysConfigService;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import com.tudouji.project.wlinfo.domain.Wlinfo;
import com.tudouji.project.wlinfo.domain.Wlinfoitem;
import com.tudouji.project.wlinfo.mapper.WlinfoitemMapper;
import com.tudouji.project.wlinfo.service.impl.WlinfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 销售订单Service业务层处理
 *
 * @author wf
 * @date 2021-01-13
 */
@Slf4j
@Service
public class SellformServiceImpl implements ISellformService, IFlowBaseService {
    @Autowired
    private SellformMapper sellformMapper;
    @Autowired
    private WlinfoServiceImpl wlinfoService;
    @Autowired
    private SellitemMapper sellitemMapper;
    @Autowired
    private DeptStoreroomMapper deptStoreroomMapper;
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private IFreightorderService freightorderService;
    @Autowired
    private FlowtempnodeServiceImpl iFlowtempnodeService;

    @Autowired
    private SellitemServiceImpl sellitemService;

    IFlowTaskMapper flowTaskMapper;
    @Autowired
    private SellspitemMapper sellspitemMapper;
    @Autowired
    private SuitpackServiceImpl suitpackService;
    @Autowired
    private SalesspecificationMapper salesspecificationMapper;
    @Autowired
    private WhoutformServiceImpl whoutformService;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private DiscountMapper discountMapper;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private FlowProcessProxy flowProcessProxy;

    @Autowired
    private SuitpackMapper suitpackMapper;

    @Autowired
    private IFlowTempNodeMapper nodeMapper;
    @Autowired
    private SalespermissionServiceImpl permissionService;

    @Autowired
    private StoreroomMapper storeroomMapper;
    @Autowired
    private ReceivableflowServiceImpl receivableflowService;
    @Autowired
    private SfPrebalanceRecordMapper sfPrebalanceRecordMapper;
    @Autowired
    private SfPrebalanceRecordServiceImpl prebalanceRecordService;
    @Autowired
    private IRechargeService rechargeService;
    @Autowired
    private IFileInfoMapper fileInfoMapper;
    @Autowired
    private IAutoTransferService autoTransferService;


    /**
     * 查询销售订单
     *
     * @return 销售订单
     */
    @Override
    public Sellform selectSellformById(Long id) {
        return sellformMapper.selectSellformById(id);
    }

    @Override
    public Sellform selectSellformByGuid(String guid) {
        return sellformMapper.selectSellformByGuid(guid);
    }

    @Override
    public SellformOld selectSellformOldByGuid(String guid) {
        return sellformMapper.selectSellformOldByGuid(guid);
    }


    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (com.tudouji.common.utils.StringUtils.isNotNull(pageNum) && com.tudouji.common.utils.StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }


    @Override
    public List<Sellform> wxList(Sellform sellform, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        if (sellform == null) {
            sellform = new Sellform();
        }

        if (org.apache.commons.lang.StringUtils.isNotBlank(status)) {
            if (status.equals("00")) {// 待处理
                sellform.setCreateBy(sysUser.getUserId());
                startPage();
                return sellformMapper.selectSellformPendingList(sellform);
            } else {
                String[] sts = status.split(",");
                Integer[] stss = (Integer[]) ConvertUtils.convert(sts, Integer.class);
                sellform.setStats(stss);
            }
        }
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return sellformMapper.selectSellformList(sellform);
        } else {
            sellform.setCreateBy(sysUser.getUserId());
            // 是否有组织权限
            List<Salespermission> permissionsOrg = permissionService
                    .getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //是否有部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");

            startPage();
            if (permissions.size() > 0 || permissionsOrg.size() > 0) {
                String[] deptids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    deptids[i] = permissions.get(i).getDepartid();
                }
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                sellform.setRoomids(roomids);
                sellform.setDepids(deptids);
                if (permissionsOrg.size() > 0 && permissions.size() > 0) {
                    sellform.setCondition("all");
                } else if (permissionsOrg.size() < 1 && permissions.size() < 1) {
                    sellform.setCondition("noall");
                } else {
                    sellform.setCondition("one");
                }
                return sellformMapper.selectSellformsByDepAndRoom(sellform);
            } else {
                //查询个人的
                return sellformMapper.selectSellformsByUser(sellform);
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult del(Long id) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        Sellform sellform = sellformMapper.selectSellformById(id);

        Sellform sellformDel = new Sellform();
        sellformDel.setId(id);
        sellformDel.setStatus(0);
        sellformMapper.updateSellform(sellformDel);
        //更新待处理任务
        processUtils.updateTaskByOrderId(id, sysUser, Long.valueOf(sellform.getFlowtempguid()));
        return AjaxResult.success();
    }

    @Override
    public AjaxResult review(Long id, String partitiontype) {
        AjaxResult result = AjaxResult.success();
        Sellform form = new Sellform();
        form.setId(id);
        form = sellformMapper.findDetail(form);
        String sellformid = form.getGuid();

        if (null != partitiontype) {
            Map<String, Object> items = this.countChildItem(form, partitiontype);
            result.put("itemsCount", items);

            Map<String, Object> handsitems = this.countHandsItem(form, partitiontype);
            result.put("handsitems", handsitems);
        }

        Wlinfo wlinfo = new Wlinfo();
        wlinfo.setRelatedid(sellformid);
        List<Wlinfo> wls = wlinfoService.selectWlinfoList(wlinfo);
        /***
         * @Author shaodong
         * @Description 套装处理：去掉销售明细中的套装部分，并与查询后的套装明细一并返回
         * @Date 11:05 2020/9/17
         * @Param
         * @return
         **/
        ArrayList<Sellitem> reItems = new ArrayList<>();
        for (int i = 0; i < form.getItems().size(); i++) {
            Sellitem item = form.getItems().get(i);
            String suitpackid = item.getSuitpackid();
            if (StringUtils.isNotBlank(suitpackid)) {
                reItems.add(item);
            }
        }
        form.getItems().removeAll(reItems);
        Sellspitem spitem = new Sellspitem();
        spitem.setSellguid(form.getGuid());
        List<Sellspitem> spitems = sellspitemMapper.findAboutSellitems(spitem);
        result.put("form", form);
        result.put("spitems", spitems);
        result.put("wl", wls);
        return result;
    }


    public Map<String, Object> countChildItem(Sellform sf, String partitiontype) {

        Sellform order = new Sellform();
        order.setParentguid(sf.getGuid());
        Map<String, Object> childitem = countItem(order);

        if (partitiontype.equals("1")) {//调度前分拆
            //计算子订单明细数量
            return childitem;
        } else {//出库后分拆
            return countItem(sf, childitem);
        }
    }

    public Map<String, Object> countHandsItem(Sellform sf, String partitiontype) {

        Sellform order = new Sellform();
        order.setParentguid(sf.getGuid());
        Map<String, Object> childitem = countHandsItem(order);

        if (partitiontype.equals("1")) {//调度前分拆
            //计算子订单明细数量
            return childitem;
        } else {//出库后分拆
            return countHandsItem(sf, childitem);
        }
    }

    public Map<String, Object> countItem(Sellform order, Map<String, Object> map) {
        //单品
        for (Sellitem item : order.getItems()) {
//            if (order.getSettletype() == 1) {//件数
//                if (map.containsKey(item.getSpguid())) {
//                    Integer count = (Integer) map.get(item.getSpguid());
//                    map.put(item.getSpguid(), item.getLoadcount() + count);
//                } else {
//                    map.put(item.getSpguid(), item.getLoadcount());
//                }
//            } else {
            if (map.containsKey(item.getSpguid())) {
                BigDecimal count = (BigDecimal) map.get(item.getSpguid());
                map.put(item.getSpguid(), count.add(item.getLoadweight() == null ? BigDecimal.ZERO : item.getLoadweight()));
            } else {
                map.put(item.getSpguid(), item.getLoadweight() == null ? BigDecimal.ZERO : item.getLoadweight());
            }
//            }
        }
        //套装
        for (Sellspitem item : order.getSpitems()) {
            if (map.containsKey(item.getSpeguid())) {
                Integer count = (Integer) map.get(item.getSpeguid());
                map.put(item.getSpeguid(), item.getLoadcount() + count);
            } else {
                map.put(item.getSpeguid(), item.getLoadcount());
            }
        }

        //总数-已分拆的部分=未分拆的部分
        List<Sellform> sell = sellformMapper.countSellOut(order.getGuid());
        List<Sellform> sellSuit = sellformMapper.countSellSuitOut(order.getGuid());
        for (int i = 0; i < sell.size(); i++) {
            Sellform item = sell.get(i);
//            if (order.getSettletype() == 1) {//件数
//                if (map.containsKey(item.getSpguid())) {
//                    Integer count = (Integer) map.get(item.getSpguid());
//                    map.put(item.getSpguid(), item.getOrderpack() - count);
//                } else {
//                    map.put(item.getSpguid(), item.getOrderpack());
//                }
//            } else {//重量
            if (map.containsKey(item.getSpguid())) {
                BigDecimal count = (BigDecimal) map.get(item.getSpguid());
                map.put(item.getSpguid(), item.getOrderweight().subtract(count));
            } else {
                map.put(item.getSpguid(), item.getOrderweight());
            }
//            }
        }
        for (Sellform sf : sellSuit) {
            if (map.containsKey(sf.getSpguid())) {
                Integer count = (Integer) map.get(sf.getSpguid());
                map.put(sf.getSpguid(), sf.getOrderpack() - count);
            } else {
                map.put(sf.getSpguid(), sf.getOrderpack());
            }
        }
        return map;
    }

    public Map<String, Object> countItem(Sellform order) {
        Map<String, Object> result = new HashMap<>();
        //已出库  单品 明细数量
        List<Sellform> sfs = sellformMapper.countOut(order);
        for (Sellform sf : sfs) {
//            if (order.getSettletype() == 1) {//件数
//                result.put(sf.getSpguid(), sf.getLoadcount() - (sf.getLoadhandsel() == null ? 0 : sf.getLoadhandsel()));
//            } else {//重量
            result.put(sf.getSpguid(), sf.getSettleweight() == null ? BigDecimal.ZERO : sf.getSettleweight());
//            }
        }

        //已出库  套装 明细数量
        List<Sellform> suitfs = sellformMapper.countSuitOut(order);
        for (Sellform sf : suitfs) {
            result.put(sf.getSpguid(), sf.getLoadcount() - (sf.getLoadhandsel() == null ? 0 : sf.getLoadhandsel()));
        }

        //未出库 单品明细数量
        List<Sellform> nsfs = sellformMapper.countNoOut(order);
        for (Sellform sf : nsfs) {
            /*if (order.getSettletype() == 1) {//件数
                if (result.containsKey(sf.getSpguid())) {
                    Integer count = (Integer) result.get(sf.getSpguid());
                    result.put(sf.getSpguid(), sf.getOrderpack() + count);
                } else {
                    result.put(sf.getSpguid(), sf.getOrderpack());
                }
            } else {*///重量
            if (result.containsKey(sf.getSpguid())) {
                BigDecimal count = (BigDecimal) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), sf.getOrderweight().add(count));
            } else {
                result.put(sf.getSpguid(), sf.getOrderweight());
            }
//            }
        }
        //未出库套装明细数量
        List<Sellform> nsuitfs = sellformMapper.countSuitNoOut(order);
        for (Sellform sf : nsuitfs) {
            if (result.containsKey(sf.getSpguid())) {
                Integer count = (Integer) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), sf.getOrderpack() + count);
            } else {
                result.put(sf.getSpguid(), sf.getOrderpack());
            }
        }

        //总数-已分拆的部分=未分拆的部分
        List<Sellform> sell = sellformMapper.countSellOut(order.getParentguid());
        List<Sellform> sellSuit = sellformMapper.countSellSuitOut(order.getParentguid());
        for (int i = 0; i < sell.size(); i++) {
            Sellform item = sell.get(i);
           /* if (order.getSettletype() == 1) {//件数
                if (result.containsKey(item.getSpguid())) {
                    Integer count = (Integer) result.get(item.getSpguid());
                    result.put(item.getSpguid(), item.getOrderpack() - count);
                } else {
                    result.put(item.getSpguid(), item.getOrderpack());
                }
            } else {*///重量
            if (result.containsKey(item.getSpguid())) {
                BigDecimal count = (BigDecimal) result.get(item.getSpguid());
                result.put(item.getSpguid(), item.getOrderweight().subtract(count));
            } else {
                result.put(item.getSpguid(), item.getOrderweight());
            }
//            }
        }
        for (Sellform sf : sellSuit) {
            if (result.containsKey(sf.getSpguid())) {
                Integer count = (Integer) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), sf.getOrderpack() - count);
            } else {
                result.put(sf.getSpguid(), sf.getOrderpack());
            }
        }

        return result;
    }

    public Map<String, Object> countHandsItem(Sellform order) {
        Map<String, Object> result = new HashMap<String, Object>();
        //已出库  单品 明细数量
        List<Sellform> sfs = sellformMapper.countOut(order);
        for (Sellform sf : sfs) {
            result.put(sf.getSpguid(), (sf.getLoadhandsel() == null ? 0 : sf.getLoadhandsel()));
        }

        //已出库  套装 明细数量
        List<Sellform> suitfs = sellformMapper.countSuitOut(order);
        for (Sellform sf : suitfs) {
            result.put(sf.getSpguid(), (sf.getLoadhandsel() == null ? 0 : sf.getLoadhandsel()));
        }

        //未出库 单品明细数量
        List<Sellform> nsfs = sellformMapper.countNoOut(order);
        for (Sellform sf : nsfs) {
            if (result.containsKey(sf.getSpguid())) {
                Integer count = (Integer) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()) + count);
            } else {
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()));
            }
        }
        //未出库套装明细数量
        List<Sellform> nsuitfs = sellformMapper.countSuitNoOut(order);
        for (Sellform sf : nsuitfs) {
            if (result.containsKey(sf.getSpguid())) {
                Integer count = (Integer) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()) + count);
            } else {
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()));
            }
        }


        //总数-已分拆的部分=未分拆的部分
        List<Sellform> sell = sellformMapper.countSellOut(order.getParentguid());
        List<Sellform> sellSuit = sellformMapper.countSellSuitOut(order.getParentguid());
        for (int i = 0; i < sell.size(); i++) {
            Sellform item = sell.get(i);
            if (result.containsKey(item.getSpguid())) {
                Integer count = (Integer) result.get(item.getSpguid());
                result.put(item.getSpguid(), (item.getHandselcount() == null ? 0 : item.getHandselcount()) - count);
            } else {
                result.put(item.getSpguid(), (item.getHandselcount() == null ? 0 : item.getHandselcount()));
            }
        }
        for (Sellform sf : sellSuit) {
            if (result.containsKey(sf.getSpguid())) {
                Integer count = (Integer) result.get(sf.getSpguid());
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()) - count);
            } else {
                result.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()));
            }
        }
        return result;
    }

    public Map<String, Object> countHandsItem(Sellform order, Map<String, Object> map) {
        //单品
        for (Sellitem item : order.getItems()) {
//            if (order.getSettletype() == 1) {//件数
            if (map.containsKey(item.getSpguid())) {
                Integer count = (Integer) map.get(item.getSpguid());
                map.put(item.getSpguid(), (item.getHandselcount() == null ? 0 : item.getHandselcount()) + count);
            } else {
                map.put(item.getSpguid(), item.getHandselcount() == null ? 0 : item.getHandselcount());
            }
//            } else {
//                if (map.containsKey(item.getSpguid())) {
//                    BigDecimal count = (BigDecimal) map.get(item.getSpguid());
//                    map.put(item.getSpguid(), (item.getHandselcount() == null ? BigDecimal.ZERO : item.getHandselcount()).add(count));
//                } else {
//                    map.put(item.getSpguid(), item.getHandselcount() == null ? BigDecimal.ZERO : item.getHandselcount());
//                }
//            }
        }
        //套装
        for (Sellspitem item : order.getSpitems()) {
            if (map.containsKey(item.getSpeguid())) {
                Integer count = (Integer) map.get(item.getSpeguid());
                map.put(item.getSpeguid(), (item.getHandselcount() == null ? 0 : item.getHandselcount()) + count);
            } else {
                map.put(item.getSpeguid(), item.getHandselcount() == null ? 0 : item.getHandselcount());
            }
        }

        //总数-已分拆的部分=未分拆的部分
        List<Sellform> sell = sellformMapper.countSellOut(order.getGuid());
        List<Sellform> sellSuit = sellformMapper.countSellSuitOut(order.getGuid());
        for (int i = 0; i < sell.size(); i++) {
            Sellform item = sell.get(i);
//            if (order.getSettletype() == 1) {//件数
            if (map.containsKey(item.getSpguid())) {
                Integer count = (Integer) map.get(item.getSpguid());
                map.put(item.getSpguid(), (item.getHandselcount() == null ? 0 : item.getHandselcount()) - count);
            } else {
                map.put(item.getSpguid(), item.getHandselcount());
            }
//            } else {//重量
//                if (map.containsKey(item.getSpguid())) {
//                    BigDecimal count = (BigDecimal) map.get(item.getSpguid());
//                    map.put(item.getSpguid(), (item.getHandselweight() == null ? BigDecimal.ZERO : item.getHandselweight()).subtract(count));
//                } else {
//                    map.put(item.getSpguid(), item.getHandselweight());
//                }
//            }
        }
        for (Sellform sf : sellSuit) {
            if (map.containsKey(sf.getSpguid())) {
                Integer count = (Integer) map.get(sf.getSpguid());
                map.put(sf.getSpguid(), (sf.getHandselcount() == null ? 0 : sf.getHandselcount()) - count);
            } else {
                map.put(sf.getSpguid(), sf.getHandselcount());
            }
        }
        return map;
    }

    /**
     * 查询销售订单列表
     *
     * @param sellform 销售订单
     * @return 销售订单
     */
    @Override
    public List<Sellform> selectSellformList(Sellform sellform) {
        //2023-10-17 设置出库时间大于系统设置的核销初始化时间
        String startDate = this.sysConfigService.selectConfigByKey("hexiao_date_start");
        sellform.setStartouttime(startDate);
        return sellformMapper.selectSellformList(sellform);
    }

    @Override
    public List<SellformListRep> pagePCList(Sellform sellform, boolean page) {
        String functionType = "1";
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            if (page) {
                startPage();
            }
            return sellformMapper.pagePCList(sellform);
        } else {
            sellform.setCreateBy(sysUser.getUserId());
            // 是否有组织权限
            List<Salespermission> permissionsOrg = permissionService
                    .getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //是否有部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");

            if (page) {
                startPage();
            }
            if (permissions.size() > 0 || permissionsOrg.size() > 0) {
                String[] deptids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    deptids[i] = permissions.get(i).getDepartid();
                }
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                sellform.setRoomids(roomids);
                sellform.setDepids(deptids);
                if (permissionsOrg.size() > 0 && permissions.size() > 0) {
                    sellform.setCondition("all");
                } else if (permissionsOrg.size() < 1 && permissions.size() < 1) {
                    sellform.setCondition("noall");
                } else {
                    sellform.setCondition("one");
                }
                return sellformMapper.pagePCList(sellform);
            } else {
                //查询个人的
                sellform.setCondition("noall");
                return sellformMapper.pagePCList(sellform);
            }
        }
    }

    @Override
    public SellformListRep pagePCListSum(Sellform sellform) {
        String functionType = "1";
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        if (sellform == null) {
            sellform = new Sellform();
        }

        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return sellformMapper.pagePCListSum(sellform);
        } else {
            sellform.setCreateBy(sysUser.getUserId());
            // 是否有组织权限
            List<Salespermission> permissionsOrg = permissionService
                    .getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //是否有部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");

            startPage();
            if (permissions.size() > 0 || permissionsOrg.size() > 0) {
                String[] deptids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    deptids[i] = permissions.get(i).getDepartid();
                }
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                sellform.setRoomids(roomids);
                sellform.setDepids(deptids);
                if (permissionsOrg.size() > 0 && permissions.size() > 0) {
                    sellform.setCondition("all");
                } else if (permissionsOrg.size() < 1 && permissions.size() < 1) {
                    sellform.setCondition("noall");
                } else {
                    sellform.setCondition("one");
                }
                return sellformMapper.pagePCListSum(sellform);
            } else {
                //查询个人的
                sellform.setCondition("noall");
                return sellformMapper.pagePCListSum(sellform);
            }
        }
    }

    /**
     * 新增销售订单
     *
     * @param sellform 销售订单
     * @return 结果
     */
    @Override
    public int insertSellform(Sellform sellform) {
        return sellformMapper.insertSellform(sellform);
    }

    /**
     * 修改销售订单
     *
     * @param sellform 销售订单
     * @return 结果
     */
    @Override
    public int updateSellform(Sellform sellform) {
        return sellformMapper.updateSellform(sellform);
    }

    /**
     * 批量删除销售订单
     *
     * @param guids 需要删除的销售订单ID
     * @return 结果
     */
    @Override
    public int deleteSellformByIds(String[] guids) {
        return sellformMapper.deleteSellformByIds(guids);
    }

    /**
     * 删除销售订单信息
     *
     * @param guid 销售订单ID
     * @return 结果
     */
    @Override
    public int deleteSellformById(String guid) {
        return sellformMapper.deleteSellformById(guid);
    }

    @Override
    public List<SellformRep> findRpt(SellformRep sellform) {
        return sellformMapper.findRpt(sellform);
    }

    @Override
    public Sellform findDetail(Sellform entity) {
        return sellformMapper.findDetail(entity);
    }

    /**
     * 根据编码查询
     *
     * @param sellcode
     * @return
     */
    @Override
    public Sellform selectSellformByCode(String sellcode) {
        return this.sellformMapper.selectSellformByCode(sellcode);
    }

    @Override
    public Sellform selectSellformRejectByCode(Sellform sellform) {
        return this.sellformMapper.selectSellformRejectByCode(sellform);
    }

    @Override
    public AjaxResult usertransfer(String touser, String fromuser) {
        Sellform sf = new Sellform();
        sf.setOperatorid(fromuser);
        List<Sellform> sfs = this.sellformMapper.findTransferForms(sf);
        for (Sellform i : sfs) {
            if (null != i) {
                i.setTransferguid(touser);
                sellformMapper.updateSellform(i);
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult saveOrUpdate(Sellform entity, Long deptId, String fileIds, Long taskid, String opinion, SysUser user) {
        List<Sellitem> sellItems = entity.getItems();

        SysDept department = deptMapper.selectDeptById(deptId);
        if (null == department) {
            return AjaxResult.error("用户未分配部门");
        }
        Organization com = organizationMapper.selectOrganizationById(department.getOrgguid());
        if (null == com) {
            return AjaxResult.error("用户公司异常");
        }
        ArrayList<Sellspitem> spitems = this.getSellspitems(entity, sellItems);
        if (spitems == null) {
            return AjaxResult.error("套装未包含任何产品，不允许下单！");
        }
        if (null != sellItems && sellItems.size() < 1) {
            return AjaxResult.error("销售明细为空!");
        }

        BigDecimal weight = new BigDecimal(0);
        BigDecimal handselweight = new BigDecimal(0);
        /*if (spitems.size() > 0) {
            for (Sellspitem spi : spitems) {
                weight = weight.add(new BigDecimal(spi.getOrderpack()));
                handselweight = handselweight.add(new BigDecimal(spi.getHandselcount() == null ? 0 : spi.getHandselcount()));
            }
        }
        for (Sellitem item : sellItems) {
            weight = weight.add(item.getWeight());
            handselweight = handselweight.add(new BigDecimal(item.getHandselcount() == null ? 0 : item.getHandselcount()));
//            item.setSettletype(entity.getSettletype());
        }*/
        //按重量计费
        //按重量计费
        if (entity.getSettletype() == 2) {
            for (Sellitem item : sellItems) {
                HashMap<String, BigDecimal> weightHash = whoutformService.calculateWeightForSaveSF(item.getSpguid(), item.getWeight(), 2, 2);
                weight = weight.add(weightHash.get(WhoutformServiceImpl.T));
            }

        } else {
            //按件
            for (Sellitem item : sellItems) {
                HashMap<String, BigDecimal> weightHash = whoutformService.calculateWeight(item.getSpguid(), item.getWeight(), 1, 2);
                HashMap<String, BigDecimal> weightHash3 = whoutformService.calculateWeight(item.getSpguid(), new BigDecimal(item.getHandselcount() == null ? 0 : item.getHandselcount()), 1, 2);
                handselweight = handselweight.add(weightHash3.get(WhoutformServiceImpl.T));
                weight = weight.add(weightHash.get(WhoutformServiceImpl.T)).add(weightHash3.get(WhoutformServiceImpl.T));
            }
        }
        AjaxResult ckResult = prebalanceCalculate(entity, spitems);
        if (HttpStatus.SUCCESS != (int) ckResult.get(AjaxResult.CODE_TAG)) {
            return ckResult;
        }

        entity.setDepguid(department.getGuid());
        entity.setDeptId(department.getDeptId());
        entity.setDepname(department.getDeptName());
        entity.setSorgguid(com.getGuid());
        entity.setOrgId(com.getId());
        entity.setOrgName(com.getName());
        entity.setHandselweight(handselweight/*.divide(new BigDecimal(1000))*/);
        entity.setOrderweight(weight);

        entity.setApplyname(user.getNickName());
        entity.setOperatorid(user.getGuid());
        entity.setCreateBy(user.getUserId());
        entity.setCreatetime(DateUtils.getNowDate());
        if (StringUtils.isNotBlank(entity.getCustomerguid())) {
            Customer customer = customerMapper.selectCustomerById(entity.getCustomerguid());
            entity.setCustomername(customer.getName());
            if (null != customer.getIsdiscount()) {
                entity.setIsdiscount(customer.getIsdiscount());
            }
        }
        //获取销售GUID
        String saleguid = entity.getGuid();
        if (StringUtils.isBlank(saleguid)) {
            saleguid = IdUtils.fastSimpleUUID();
        }

        if (spitems.size() > 0) {
            for (Sellspitem sitem : spitems) {
                sitem.setSellguid(saleguid);
                sellspitemMapper.updateSellspitem(sitem);
            }
        }
        List<Sellitem> upSellItem = new ArrayList<>();
        for (Sellitem i : sellItems) {
            i.setSellguid(saleguid);
            if (StringUtils.isBlank(i.getGuid())) {
                i.setGuid(IdUtils.fastSimpleUUID());
                i.setCreateBy(user.getUserId());
                i.setCreateTime(DateUtils.getNowDate());
                sellitemMapper.insertSellitem(i);
            } else {
                i.setUpdateBy(user.getUserId());
                i.setUpdateTime(DateUtils.getNowDate());
                sellitemMapper.updateSellitem(i);
            }
            upSellItem.add(i);
        }

        if (StringUtils.isBlank(entity.getGuid())) {
            entity.setStatus(-1);// 预设一个状态值
            entity.setGuid(saleguid);
            //20230612预收款判断修改
            entity.setFinalamount((BigDecimal) ckResult.get(AjaxResult.DATA_TAG));
            entity.setAmount((BigDecimal) ckResult.get(AjaxResult.DATA_TAG));
            //2023.09.05地头直销类采收订单关联发起的销售订单
            if (StringUtils.equalsIgnoreCase(entity.getLinkedCode(), "freightorder")) {
                entity.setAutoType(2);
            }

            String code = codeService.getCode("1");
            entity.setSellcode(code);
            sellformMapper.insertSellform(entity);
            String productTypes = sellformMapper.selectProductTypesByItems(saleguid);
            if (productTypes.contains(",")){
                throw new CustomException("产品不允许跨类！");
            }

            Sellform sfT = new Sellform();
            sfT.setGuid(saleguid);
            sfT.setProductTypes(productTypes);
            sellformMapper.updateSellform(sfT);

            //2023.09.05销售订单发起后，系统根据关联订单判断如果是采收订单
            if (StringUtils.equalsIgnoreCase(entity.getLinkedType(), "freightorder") && entity.getAutoType() == 2) {
                Freightorder freightorder = freightorderService.selectFreightorderDetailByAutoId(entity.getLinkedId());
//                if (freightorder.getPaystatus() == 27){//状态是“发起销售订单”
                freightorder.setSellformId(entity.getId());
                freightorder.setSellformCode(entity.getSellcode());
                freightorderService.updateFreightorder(freightorder);
                //2023.09.05查询到采收订单的“发起销售订单”待处理任务，系统自动完成该节点的审批
                FlowTempNode node = new FlowTempNode();
                node.setOrderId(entity.getLinkedId());
//                    node.setCreateBy(1L);
                node.setFlowId(freightorder.getFlowId());
                List<FlowTempNode> nodes = iFlowtempnodeService.getPendingNodes(node);
                /*AjaxResult result = */
                freightorderService.approval(entity.getLinkedId(), nodes.get(0).getFlowTaskId(), null, null);
//                    if ((result.get(CODE_TAG)).equals(200)) {
//                        throw new CustomException("采收订单自动审批失败！");
//                    }
//                }else{
//                    return AjaxResult.error("货运单状态不正确！");
//                }
            }
            entity.setPlatformId(entity.getStrmId());
            entity.setCode(entity.getSellcode());


            //20230404用户由方法入参传入
//            SysUser sysUser = SecurityUtils.getLoginUser().getUser();
            FlowResult result = flowProcessProxy.start(processUtils.getStartNode(Long.valueOf(entity.getFlowtempguid())), entity, fileIds
                    , user);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Sellform sf = new Sellform();

                sf.setStatus(result.getNextStat());
                sf.setGuid(saleguid);
                updateSellform(sf);
                return AjaxResult.success(saleguid);
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error(result.getMsg());
            }
        } else {

            Sellform sf = sellformMapper.selectSellformByGuid(entity.getGuid());

            // 判断是否更新,如果是更新 判断有无删除明细
            Sellitem item = new Sellitem();
            item.setSellguid(entity.getGuid());
            List<Sellitem> items = sellitemMapper.selectSellitemList(item);
            List<String> ids = new ArrayList<>();
            for (Sellitem it : items) {
                ids.add(it.getGuid());
            }
            for (Sellitem pit : sellItems) {
                ids.remove(pit.getGuid());
            }
            if (ids.size() > 0) {
                for (String id : ids) {
                    sellitemMapper.deleteSellitemById(id);
                }
            }
            //2023-04-28 如果是自动发起的电商订单，重新发起后，修改auto_type=2
            if (sf.getAutoType() == 1) {
                entity.setAutoType(2);
            }
            entity.setPlatformId(entity.getStrmId());
            entity.setStatus(sf.getStatus());
            String productTypes = sellformMapper.selectProductTypesByItems(entity.getGuid());
            if (productTypes.contains(",")){
                throw new CustomException("产品不允许跨类！");
            }
            entity.setProductTypes(productTypes);
            entity.setGuid(entity.getGuid());
            //20230612预收款判断修改
            entity.setFinalamount((BigDecimal) ckResult.get(AjaxResult.DATA_TAG));
            this.updateSellform(entity);
//            entity.setCode(sf.getSellcode());
            entity.setSellcode(sf.getSellcode());
            //20230404用户由方法入参传入
//            SysUser sysUser = SecurityUtils.getLoginUser().getUser();
            FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, entity, user);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Sellform entityResult = new Sellform();
                entityResult.setStatus(result.getNextStat());
                //entityResult.setGuid(entityResult.getGuid());
                entityResult.setGuid(entity.getGuid());
                updateSellform(entityResult);
                return AjaxResult.success();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error(result.getMsg());
            }
        }
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult nbdj(Sellform entity, Long taskid, String opinion, String fileIds) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<Sellitem> sellItems = entity.getItems();

        if ((null != sellItems && sellItems.size() < 1)) {
            return AjaxResult.error("销售明细为空!");
        }
        if (null != sellItems && sellItems.size() > 0){
            for (Sellitem i : sellItems) {
                i.setUpdateBy(user.getUserId());
                i.setUpdateTime(DateUtils.getNowDate());
                sellitemMapper.updateSellitem(i);
            }
        }

        Sellform sf = sellformMapper.selectSellformByGuid(entity.getGuid());
        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, sf, user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Sellform entityResult = new Sellform();
            entityResult.setStatus(result.getNextStat());
            entityResult.setGuid(entity.getGuid());
            updateSellform(entityResult);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    public ArrayList<Sellspitem> getSellspitems(Sellform entity, List<Sellitem> sellItems) {
        ArrayList<Sellspitem> spitems = new ArrayList<>();
        ArrayList<Sellitem> pitemsCopy = new ArrayList<>();
        ArrayList<Sellitem> repitemsCopy = new ArrayList<>();

        if (StringUtils.isNotBlank(entity.getGuid())) {
            Sellspitem spitem = new Sellspitem();
            spitem.setSellguid(entity.getGuid());
            List<Sellspitem> sellspitems = sellspitemMapper.selectSellspitemListBySellguid(entity.getGuid());
            for (Sellspitem spi : sellspitems) {
                sellspitemMapper.deleteSellspitemById(spi.getGuid());
            }
        }

        for (int i = 0; i < sellItems.size(); i++) {
            System.out.println("sellItems: " + sellItems.get(i).toString());
            Sellitem pi = sellItems.get(i);
            int flag = pi.getFlag();
            Salesspecification spec = salesspecificationMapper.selectSalesspecificationById(pi.getSpguid());

            pi.setSettletype(spec.getValuation());
            pi.setSettlePrice(pi.getPrice());
//            if (spec.getValuation().equals(1)) {
//                pi.setSfunitid(spec.getStockunitid());
//                pi.setStockunit(spec.getStockunit());
//            } else {
            //自动生成的电商订单如果商品对应的是次品/原料的话，设置销售订单明细的销售单位为KG
            /*if (1== entity.getAutoType() && 4 == entity.getFlag() && (1 == spec.getType() || 3 == spec.getType())){
                pi.setSfunitid(3L);
                pi.setStockunit("公斤");
                pi.setUnit("公斤");
            }else {*/
            pi.setSfunitid(spec.getSfunitid());
            pi.setUnit(spec.getUnit());
            //20240129 备注：出入库单明细添加销售单位id,名称，转换率，销售明细添加转换率
            // 等到跑几个月之后，明细中有了这些数据之后，将出入库时从物料查找销售单位修改为从出入库明细中获取
            // 再跑几个月之后，修改推送任务中获取销售单位的逻辑
            pi.setBusiunitTostockunitRate(spec.getNetweight());
            pi.setStockunit(spec.getStockunit());
//            }
//            }

            if (2 == flag) {//套装
//                String suitpackid = pi.getGuid();
                Sellspitem spitem = new Sellspitem();
                spitem.setProductid(pi.getProductguid());
                spitem.setSpeguid(pi.getSpguid());
                spitem.setOrderpack(pi.getWeight().intValue());
                spitem.setPrice(pi.getPrice());
                spitem.setDeductrate(pi.getDeductrate());
                spitem.setHandselcount(pi.getHandselcount());

                String suitpackid = IdUtils.fastSimpleUUID();
                spitem.setGuid(suitpackid);
                sellspitemMapper.insertSellspitem(spitem);
                List<Sellitem> packItems = suitpackService.findchildSp(pi, suitpackid, spec.getName());
                if (packItems.size() == 0) {
                    return null;
                }
                BigDecimal amountWeight = BigDecimal.ZERO;
                BigDecimal itemsPercent = BigDecimal.ZERO;
                for (int j = 0; j < packItems.size(); j++) {
                    Sellitem item = packItems.get(j);
                    BigDecimal itemWeight = item.getPrice().multiply(item.getWeight() == null ? BigDecimal.ZERO : item.getWeight());
                    amountWeight = amountWeight.add(itemWeight);
                }
                for (int j = 0; j < packItems.size(); j++) {
                    Sellitem item = packItems.get(j);
                    if (j == (packItems.size() - 1)) {//最后一个
                        BigDecimal endItemPercent = BigDecimal.ONE.subtract(itemsPercent);
                        item.setPrice(pi.getPrice().multiply(endItemPercent));
                        break;
                    }
                    BigDecimal itemWeight = item.getPrice().multiply(item.getWeight() == null ? BigDecimal.ZERO : item.getWeight());
                    BigDecimal itemPercent = itemWeight.divide(amountWeight, 2, BigDecimal.ROUND_HALF_DOWN);
                    item.setPrice(pi.getPrice().multiply(itemPercent));
                    itemsPercent = itemsPercent.add(itemPercent);
                }

                spitems.add(spitem);
                repitemsCopy.add(pi);
                pitemsCopy.addAll(packItems);
            }
        }
        sellItems.removeAll(repitemsCopy);
        sellItems.addAll(pitemsCopy);
        return spitems;
    }

    /**
     * @return void
     * @auther shaodong
     * @desc 销售下单客户预收款余额验证：客户预收款余额-客户应收账款-SUM(未结算,未作废订单订单金额)
     * .compareTo(当前订单订单金额)  = -1
     * A < B
     * @Date 10:47 2020/6/18
     * @Param []
     **/
    private AjaxResult prebalanceCalculate(Sellform entity, List<Sellspitem> spitems) {

        List<Sellitem> pitems = entity.getItems();
        //新销售订单预收款余额判断逻辑，过渡期两种判断的和才能确定
        BigDecimal curr_Order_Amt = new BigDecimal(0);
        for (Sellitem b : pitems) {
            if (StringUtils.isBlank(b.getSuitpackid())) {
                curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply((b.getWeight())));
            }
        }
        //套装
        if (spitems.size() > 0) {
            for (Sellspitem b : spitems) {
                curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())));
            }
        }
        curr_Order_Amt = curr_Order_Amt.setScale(2, RoundingMode.HALF_UP);

        if (entity.getPaytype() == 1) {
            Customer customer = customerMapper.selectCustomerById(entity.getCustomerguid());
            BigDecimal bal = customer.getPrebalance();

//            HashMap<String, Object> oldPrebalanceMap = getPrebalanceZYOld(entity.getCustomerguid());

            //新销售订单预收款余额判断逻辑，过渡期两种判断的和才能确定
            HashMap<String, Object> newPrebalanceMap = getPrebalanceZYNew(entity.getCustomerguid());

//            BigDecimal ordersbalancedOld = (BigDecimal)oldPrebalanceMap.get("ordersbalanced");
//            BigDecimal ordersbalanceOld = (BigDecimal)oldPrebalanceMap.get("ordersbalance");
            BigDecimal ordersbalance1New = (BigDecimal) newPrebalanceMap.get("ordersbalance1");
            BigDecimal ordersbalanced1New = (BigDecimal) newPrebalanceMap.get("ordersbalanced1");
            log.info("当前客户预收款余额：" + bal);
//            log.info("flowid=2的销售订单的总金额1：" + ordersbalancedOld);
//            log.info("flowid=2的销售订单的总金额2：" + ordersbalanceOld);
            log.info("flowid=36的销售订单的总金额1：" + ordersbalance1New);
            log.info("flowid=36的销售订单的总金额2：" + ordersbalanced1New);
            log.info("当前下单总金额：" + curr_Order_Amt);
            if (bal.subtract(ordersbalance1New)/*.subtract(ordersbalanceOld)*/.subtract(ordersbalanced1New)
                    /*.subtract(ordersbalancedOld)*/.subtract(curr_Order_Amt).compareTo(BigDecimal.ZERO) == -1) {
                AjaxResult json = AjaxResult.error();
                json.put("msg", "yz");
                JSONObject result = new JSONObject();
                result.put("prebalance", bal);
                BigDecimal ztbalance = /*ordersbalanceOld.add(*/ordersbalance1New/*).add(ordersbalancedOld)*/.add(ordersbalanced1New);
                result.put("ztbalance", ztbalance.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                result.put("kybalance", bal.subtract(ztbalance).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                result.put("balance", curr_Order_Amt.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                json.put("result", result);
                return json;
            }
        }
        return AjaxResult.success(curr_Order_Amt);
    }

    /**
     * 新流程36被占用的预收款计算
     *
     * @param customerguid
     * @return
     */
    public HashMap<String, Object> getPrebalanceZYNew(String customerguid) {
        HashMap<String, Object> newPrebalanceMap = new HashMap<>();
        BigDecimal ordersbalance1 = new BigDecimal(0);
        BigDecimal ordersbalanced1 = new BigDecimal(0);
        //已结算
        Sellform sfa1 = new Sellform();
        sfa1.setCustomerguid(customerguid);
        sfa1.setPaytype(1);
//        sfa1.setMoneybackStatus(1);
        sfa1.setMoneybackStatusNo(3);
        sfa1.setFlowtempguid("36");
        sfa1.setPartitionflagNo(2);
        sfa1.setMinstatusL("65");
        List<Sellform> sfsAmount1 = sellformMapper.selectSellformList(sfa1);
        for (Sellform a : sfsAmount1) {
            if (null != a) {
                ordersbalanced1 = ordersbalanced1.add(a.getFinalamount());
            }
        }
        //主订单
        Sellform sfaZ = new Sellform();
        sfaZ.setCustomerguid(customerguid);
        sfaZ.setPaytype(1);
//        sfa1.setMoneybackStatus(1);
        sfaZ.setMoneybackStatusNo(3);
        sfaZ.setFlowtempguid("36");
        sfaZ.setPartitionflag(2);
        sfaZ.setMaxstatusL("100");
        List<Sellform> sfsAmountZ = sellformMapper.selectSellformList(sfaZ);
        for (Sellform a : sfsAmountZ) {
            if (null != a) {
                ordersbalanced1 = ordersbalanced1.add(a.getFinalamount());
            }
        }

        //未出库
        Sellform sf1 = new Sellform();
        sf1.setCustomerguid(customerguid);
        sf1.setPaytype(1);
//        sf1.setMoneybackStatus(1);
        sf1.setMoneybackStatusNo(3);
        sf1.setFlowtempguid("36");
        sf1.setMinstatusL("0");
        sf1.setMaxstatus("55");
        sf1.setPartitionflagNo(2);
        List<Sellform> sfs1 = sellformMapper.selectSellformList(sf1);
        for (Sellform a : sfs1) {
            if (null != a) {
                Sellitem sfItem = new Sellitem();
                sfItem.setSellguid(a.getGuid());
                List<Sellitem> sfItems = sellitemMapper.selectSellitemList(sfItem);
                BigDecimal balance = new BigDecimal(0);
                for (Sellitem b : sfItems) {
                    if (StringUtils.isBlank(b.getSuitpackid())) {
                        balance = balance.add(b.getPrice().multiply((b.getWeight())).setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                }
                Sellspitem spI = new Sellspitem();
                spI.setSellguid(a.getGuid());
                List<Sellspitem> spItems = sellspitemMapper.selectSellspitemList(spI);
                if (spItems.size() > 0) {
                    for (Sellspitem b : spItems) {
                        balance = balance.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())).setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                }
                a.setFinalamount(balance);
                ordersbalance1 = ordersbalance1.add(balance);
            }
        }
        //已出库
        Sellform sf2 = new Sellform();
        sf2.setCustomerguid(customerguid);
        sf2.setPaytype(1);
//        sf2.setMoneybackStatus(1);
        sf2.setMoneybackStatusNo(3);
        sf2.setFlowtempguid("36");
        sf2.setMinstatusL("55");
        sf2.setMaxstatus("65");
        sf2.setPartitionflagNo(2);
        List<Sellform> sfs2 = sellformMapper.selectSellformList(sf2);
        for (Sellform a : sfs2) {
            if (null != a) {
                Sellitem sfItem = new Sellitem();
                sfItem.setSellguid(a.getGuid());
                List<Sellitem> sfItems = sellitemMapper.selectSellitemList(sfItem);
                BigDecimal balance = new BigDecimal(0);
                for (Sellitem b : sfItems) {
                    if (StringUtils.isBlank(b.getSuitpackid())) {
                        balance = balance.add(b.getPrice().multiply((b.getLoadweight()
                                .subtract(new BigDecimal(b.getLoadhandsel() == null ? 0 : b.getLoadhandsel())))));
                    }
                }
                Sellspitem spI = new Sellspitem();
                spI.setSellguid(a.getGuid());
                List<Sellspitem> spItems = sellspitemMapper.selectSellspitemList(spI);
                if (spItems.size() > 0) {
                    for (Sellspitem b : spItems) {
                        balance = balance.add(b.getPrice().multiply(new BigDecimal(b.getLoadcount() - (b.getLoadhandsel() == null ? 0 : b.getLoadhandsel()))).setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                }
                a.setFinalamount(balance);
                ordersbalance1 = ordersbalance1.add(balance);
            }
        }

        ordersbalance1 = (ordersbalance1 == null ? BigDecimal.ZERO : ordersbalance1);
        ordersbalanced1 = (ordersbalanced1 == null ? BigDecimal.ZERO : ordersbalanced1);
        newPrebalanceMap.put("ordersbalance1", ordersbalance1);
        newPrebalanceMap.put("ordersbalanced1", ordersbalanced1);
        sfsAmount1.addAll(sfs1);
        sfsAmount1.addAll(sfs2);
        sfsAmount1.addAll(sfsAmountZ);
        newPrebalanceMap.put("sellformNews", sfsAmount1);
        return newPrebalanceMap;
    }

    /**
     * 老流程2被占用的预收款计算
     *
     * @param customerguid
     * @return
     */
    public HashMap<String, Object> getPrebalanceZYOld(String customerguid) {
        HashMap<String, Object> oldPrebalanceMap = new HashMap<>();
        BigDecimal ordersbalance = new BigDecimal(0);
        BigDecimal ordersbalanced = new BigDecimal(0);
        Sellform sfa = new Sellform();
        sfa.setCustomerguid(customerguid);
        sfa.setPaytype(1);
        sfa.setFlowtempguid("2");
        sfa.setStats(new Integer[]{60, 65});
        List<Sellform> sfsAmount = sellformMapper.selectSellformList(sfa);
        for (Sellform a : sfsAmount) {
            if (null != a) {
                ordersbalanced = ordersbalanced.add(a.getFinalamount());
            }
        }

        Sellform sf = new Sellform();
        sf.setCustomerguid(customerguid);
        sf.setPaytype(1);
        sf.setFlowtempguid("2");
        sf.setNostats(new Integer[]{0, 60, 65, 70, 71, 72, -1});
        List<Sellform> sfs = sellformMapper.selectSellformList(sf);
        for (Sellform a : sfs) {
            if (null != a) {
                Sellitem sfItem = new Sellitem();
                sfItem.setSellguid(a.getGuid());
                List<Sellitem> sfItems = sellitemMapper.selectSellitemList(sfItem);
                BigDecimal balance = new BigDecimal(0);
                if (2 == a.getSettletype()) {
                    for (Sellitem b : sfItems) {
                        balance = balance.add(b.getWeight().multiply(b.getPrice()));
                    }
                }
                if (1 == a.getSettletype()) {
                    for (Sellitem b : sfItems) {
                        if (StringUtils.isBlank(b.getSuitpackid())) {
                            balance = balance.add(b.getPrice().multiply((new BigDecimal(b.getOrderpack()))));
                        }
                    }
                }
                Sellspitem spI = new Sellspitem();
                spI.setSellguid(a.getGuid());
                List<Sellspitem> spItems = sellspitemMapper.selectSellspitemList(spI);
                if (spItems.size() > 0) {
                    for (Sellspitem b : spItems) {
                        balance = balance.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())));
                    }
                }
                a.setFinalamount(balance);
                ordersbalance = ordersbalance.add(balance);
            }
        }

        sfsAmount.addAll(sfs);
        oldPrebalanceMap.put("ordersbalance", ordersbalance);
        oldPrebalanceMap.put("ordersbalanced", ordersbalanced);
        oldPrebalanceMap.put("sellformOlds", sfsAmount);
        return oldPrebalanceMap;
    }


    @Transactional
    @Override
    public AjaxResult approval(Long id, Long taskid, String opinion, String fileIds) {
        Sellform sale = sellformMapper.selectSellformById(id);
        sale.setPlatformId(sale.getStrmId());
        sale.setCode(sale.getSellcode());
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, sale
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            /*Sellform sf = new Sellform();
            sf.setStatus(result.getNextStat());
            sf.setId(id);
            updateSellform(sf);*/
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Transactional
    @Override
    public AjaxResult zgsp(Long id, Long taskid, String opinion, String fileIds, Integer innerOut) {
        if (1 == innerOut){
            Sellform sf = sellformMapper.selectSellformById(id);
            DeptStoreroom deptStoreroom = new DeptStoreroom();
            deptStoreroom.setDeptId(sf.getDeptId());
            List<DeptStoreroom> deptStoreroomList = deptStoreroomMapper.selectDeptStoreroomList(deptStoreroom);
            if (deptStoreroomList.size() == 0){
                return AjaxResult.error("当前部门没有内部库房，不能内部出货！");
            }
        }
        Sellform sale = new Sellform();
        sale.setId(id);
        sale.setInnerOut(innerOut);
        sellformMapper.updateSellform(sale);
        return this.approval(id, taskid, opinion, fileIds);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult refuse(Long id, String fileIds, String opinion, Long taskid, Long refuseNodeid
            , Long backUserid) {
        Sellform sale = sellformMapper.selectSellformById(id);
        sale.setPlatformId(sale.getStrmId());
        sale.setCode(sale.getSellcode());
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        Sellform sellform = new Sellform();
        sellform.setParentguid(sale.getGuid());
        sellform.setNostats(new Integer[]{0});
        List<Sellform> sellforms = sellformMapper.selectSellformList(sellform);
        if (sellforms.size() > 0) {
            return AjaxResult.error("订单已拆分，不能拒绝、或者将已拆分订单删除！");
        }

        FlowResult result = flowProcessProxy.refuse(taskid, fileIds, opinion, sale
                , sysUser, refuseNodeid, backUserid);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Sellform sf = new Sellform();
            sf.setStatus(result.getNextStat());
            sf.setId(id);
            updateSellform(sf);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Transactional
    @Override
    public AjaxResult dispatch(Sellform sellform, Long taskid, String opinion, String fileIds) {

        log.info("*********settledays********{}", sellform.getSettledays());
        sellform.setStrmName(sellform.getStoreroomname());
        sellformMapper.updateSellform(sellform);

        Sellform sale = sellformMapper.selectSellformById(sellform.getId());
        try {
            int innerPriceFlag = sellformMapper.selectInnerPriceFlag(sale.getGuid());
            if (innerPriceFlag != 1) {
                Storeroom rom = storeroomMapper.selectStoreroomById(sellform.getStrmId());
                sellform.setSorgguid(rom.getOrgguid());
                sellform.setOrgId(rom.getOrgId());
                sellform.setOrgName(rom.getOrgname());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("不允许完成直接调度，订单多个产品内部结算标识不一致，请先拆分订单！");
        }

        log.info("*********settledays********{}", sale.getSettledays());
        log.info("---StrmId:{}", sellform.getStrmId());
        sale.setPlatformId(sellform.getStrmId());
        sale.setCode(sale.getSellcode());
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, sale
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            sellform.setStatus(result.getNextStat());
            sellformMapper.updateSellform(sellform);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Transactional
    @Override
    public AjaxResult partition(Long taskid, String fileIds, Sellform sell) {
        SysUser user = SecurityUtils.getLoginUser().getUser();

        //生成销售子订单
        Sellform sf = sellformMapper.selectSellformById(sell.getId());
        Sellform newsf = sf;
        //20230612预售款完善
        BigDecimal finalAmount = BigDecimal.ZERO;

        Storeroom rom = storeroomMapper.selectStoreroomById(sell.getStrmId());
        newsf.setStrmName(rom.getName());
        newsf.setStrmId(rom.getId());
        newsf.setStorermguid(sell.getStorermguid());
        newsf.setStoreroomname(sell.getStoreroomname());
        newsf.setDeliProvince(rom.getProvince());
        newsf.setDeliCity(rom.getCity());
        newsf.setDeliDistrict(rom.getArea());
        newsf.setDeliAddress(rom.getAddress());
        newsf.setDeliContact(rom.getContact());
        newsf.setDeliContactNo(rom.getContacttel());

        log.info("----StoreOrgId------{}", sell.getStoreOrgId());
        log.info("----StoreOrgName------{}", sell.getStoreOrgName());
        log.info("----Storermguid------{}", sell.getStorermguid());
        newsf.setStoreOrgId(sell.getStoreOrgId());
        newsf.setStoreOrgName(sell.getStoreOrgName());
        newsf.setStorermguid(sell.getStorermguid());

        if (sell.getStorermguid().equals(sf.getStorermguid())) {
            newsf.setPartitionflag(3);
        } else {
            newsf.setPartitionflag(4);//跨库房子订单
        }

        //获取子订单数量
        Integer count = sellformMapper.findChiledCount(sf.getGuid());

        newsf.setParentcode(sf.getSellcode());
        newsf.setParentguid(sf.getGuid());
        newsf.setGuid("");
        newsf.setSellcode(sf.getSellcode().concat("-").concat((count + 1) + ""));
        String guid = UUIDCreate.get();
        newsf.setGuid(guid);

        //明细处理
        BigDecimal orderweight = BigDecimal.ZERO;//订单重量
        BigDecimal handselweight = BigDecimal.ZERO;//赠送重量
        //内部核算检查
        List<Sellspitem> spitems = sell.getSpitems();
        List<Sellitem> items = sell.getItems();
        String[] spGuids = new String[spitems.size() + items.size()];
        if (spitems != null) {
            for (int i = 0; i < spitems.size(); i++) {
                Sellspitem pitem = sellspitemMapper.selectSellspitemById(spitems.get(i).getGuid());
                spGuids[i] = pitem.getSpeguid();
            }
        }
        if (items != null) {
            for (int i = 0; i < items.size(); i++) {
                Sellitem item = sellitemMapper.selectSellitemById(items.get(i).getGuid());
                spGuids[spitems.size() + i] = item.getSpguid();
            }
        }
        try {
            Sellform innerSf = new Sellform();
            innerSf.setSpGuids(spGuids);
            int innerFlag = sellformMapper.selectInnerPriceFlagByItems(innerSf);
            if (innerFlag != 1) {
                newsf.setSorgguid(rom.getOrgguid());
                newsf.setOrgId(newsf.getStoreOrgId());
                newsf.setOrgName(newsf.getStoreOrgName());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("产品内部核算标识不一致,请重新分拆!");
        }

        //套装处理
        if (spitems != null) {
            for (Sellspitem it : spitems) {
                if (it != null && StringUtils.isNotBlank(it.getGuid())) {
                    Sellspitem pitem = sellspitemMapper.selectSellspitemById(it.getGuid());
                    it.setSellguid(guid);
                    String spid = UUIDCreate.get();
                    it.setGuid(spid);
                    it.setProductid(pitem.getProductid());
                    it.setSpeguid(pitem.getSpeguid());
                    it.setPrice(pitem.getPrice());
                    it.setOrderpack(it.getWeight());
                    finalAmount = finalAmount.add(it.getPrice().multiply(new BigDecimal(it.getWeight())));
                    sellspitemMapper.insertSellspitem(it);

                    //拆分成普通明细
                    //1.查询套装 明细
                    List<Suitpack> packs = suitpackMapper.findDetail(it.getSpeguid());
                    for (Suitpack pa : packs) {
                        Sellitem item = new Sellitem();
                        item.setSellguid(guid);
                        item.setSuitpackid(spid);
                        item.setSuitname(pa.getSpename());
                        item.setSpguid(pa.getChildspid());
                        item.setProductguid(pa.getProductid());
                        item.setSpname(pa.getSpename());
                        item.setProductname(pa.getProduct());
                        item.setWeight(new BigDecimal(pa.getAmount() * it.getWeight()));
                        item.setPrice(pa.getPrice());
                        item.setHandselcount(pa.getAmount() * (it.getHandselcount() == null ? 0 : it.getHandselcount()));
                        item.setSettletype(1);

                        Salesspecification spec = salesspecificationMapper.selectSalesspecificationById(pa.getChildspid());

                        item.setSfunitid(spec.getSfunitid());
                        item.setStockunit(spec.getStockunit());

                        //明细重量=(包材+净重)*订单数量
                        //20230414去掉重量计算，weight不代表重量，代表数量
//                        item.setWeight(((pa.getWeight() == null ? BigDecimal.ZERO : pa.getWeight())).multiply(item.getWeight()).divide(BigDecimal.valueOf(1000)));
                        item.setUnit(pa.getUnit());
                        String itemguid = UUIDCreate.get();
                        item.setGuid(itemguid);
                        item.setCreateBy(user.getUserId());
                        item.setCreateTime(DateUtils.getNowDate());
                        //计算订单重量
                        HashMap<String, BigDecimal> weightHash = whoutformService.calculateWeight(item.getSpguid(), item.getWeight(), 1, 2);
                        HashMap<String, BigDecimal> weightHash3 = whoutformService.calculateWeight(pitem.getSpeguid(), new BigDecimal(item.getHandselcount() == null ? 0 : item.getHandselcount()), 1, 2);
                        handselweight = handselweight.add(weightHash3.get(WhoutformServiceImpl.T));
                        orderweight = orderweight.add(weightHash.get(WhoutformServiceImpl.T)).add(weightHash3.get(WhoutformServiceImpl.T));

                        sellitemMapper.insertSellitem(item);
                    }
                }
            }
        }
        if (items != null) {
            //单品明细
            for (Sellitem it : items) {
                if (it != null && StringUtils.isNotBlank(it.getGuid())) {
                    Sellitem item = sellitemMapper.selectSellitemById(it.getGuid());
                    Salesspecification spe = salesspecificationMapper.selectSalesspecificationById(item.getSpguid());
                    orderweight = orderweight.add(it.getWeight());
                    handselweight = handselweight.add(new BigDecimal(it.getHandselcount() == null ? 0 : it.getHandselcount()));
                    it.setProductguid(item.getProductguid());
                    it.setProductname(item.getProductname());
                    it.setSpguid(item.getSpguid());
                    it.setSpname(spe.getName());
                    it.setPrice(item.getPrice());
                    it.setInnerPrice(item.getInnerPrice());

                    it.setSettlePrice(item.getSettlePrice());
                    it.setUnit(item.getUnit());

                    it.setSfunitid(spe.getSfunitid());
                    it.setStockunit(spe.getUnit());
                    it.setSellguid(guid);
                    String itemGuid = UUIDCreate.get();
                    it.setGuid(itemGuid);
                    it.setCreateBy(user.getUserId());
                    it.setCreateTime(DateUtils.getNowDate());
                    //计算重量
                    BigDecimal weight = new BigDecimal(0);
                    if (newsf.getSettletype() == 2) {
                        HashMap<String, BigDecimal> weightHash = whoutformService.calculateWeightForSaveSF(item.getSpguid(), item.getWeight(), 2, 2);
                        orderweight = weight.add(weightHash.get(WhoutformServiceImpl.T));
                    } else {
                        HashMap<String, BigDecimal> weightHash = whoutformService.calculateWeight(item.getSpguid(), item.getWeight(), 1, 2);
                        HashMap<String, BigDecimal> weightHash3 = whoutformService.calculateWeight(item.getSpguid(), new BigDecimal(item.getHandselcount() == null ? 0 : item.getHandselcount()), 1, 2);
                        handselweight = handselweight.add(weightHash3.get(WhoutformServiceImpl.T));
                        orderweight = weight.add(weightHash.get(WhoutformServiceImpl.T)).add(weightHash3.get(WhoutformServiceImpl.T));
                    }
                    finalAmount = finalAmount.add(it.getPrice().multiply(it.getWeight()));
                    sellitemMapper.insertSellitem(it);
                }
            }
        }

        Sellform sef = sellformMapper.selectSellformById(sell.getId());
        sell.setSettledays(sell.getSettledays());
        sef.setPartitionflag(2);//2分拆主订单
        sef.setSettledays(sell.getSettledays());//是否继续拆分
        //历史订单预收款不通过finalAmount判断
        if (null != sef.getFinalamount()) {
            sef.setFinalamount(sef.getFinalamount().subtract(finalAmount));
        }
        sellformMapper.updateSellform(sef);

        sell.setPaytype(sf.getPaytype());
        sell.setCustomerguid(sf.getCustomerguid());
        AjaxResult ckResult = prebalanceCalculate(sell, spitems);
        if (HttpStatus.SUCCESS != (int) ckResult.get(AjaxResult.CODE_TAG)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ckResult;
        }
        newsf.setFinalamount(finalAmount);
        sellformMapper.insertSellform(newsf);

        FlowResult result;
        newsf.setPlatformId(newsf.getStrmId());
        sef.setPlatformId(sef.getStrmId());

        sef.setCode(sef.getSellcode());
        newsf.setCode(newsf.getSellcode());
//        FlowResult result1 = flowProcessProxy.approval(taskid, fileIds, "分拆生成子订单:" + newsf.getSellcode(), sef
//                , user);
//        log.info("-----分拆返回：-----" + result1);
        FlowTempNode node = new FlowTempNode();
        node.setNodeType(11);
        node.setFlowtempId(Long.valueOf(newsf.getFlowtempguid()));
        List<FlowTempNode> nodes = nodeMapper.selectFlowTempNodeList(node);
        node = nodes.get(0);
        //跑子订单开始流程
        result = flowProcessProxy.start(node.getId(), newsf, fileIds, user);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            //更新子订单 订单数量、重量等信息
            Sellform childsf = new Sellform();
            childsf.setStatus(result.getNextStat());
            childsf.setGuid(guid);
            childsf.setHandselweight(handselweight);
            childsf.setOrderweight(orderweight);
            sellformMapper.updateSellform(childsf);

            //更新主订单
            /*if (null != result1.getNextStat()) {
                Sellform order = new Sellform();
                order.setId(sef.getId());
                order.setStatus(result1.getNextStat());
                sellformMapper.updateSellform(order);
            }*/
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Transactional
    @Override
    public AjaxResult partOrDispatch(Long taskid, String fileIds, Sellform sellform, String opinion) {
        if (sellform.getSettledays() == 1) {
            return dispatch(sellform, taskid, opinion, fileIds);
        } else if (sellform.getSettledays() == 2) {
            return partition(taskid, fileIds, sellform);
        } else {
            sellformMapper.updateSellform(sellform);
            return approval(sellform.getId(), taskid, opinion, fileIds);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whoutBack(Long id, String fileIds, String opinion, Long taskid) {

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Sellform sellform = new Sellform();
        sellform.setId(id);
        sellform = sellformMapper.findDetail(sellform);

        //202306123预收款判断处理
        if (sellform.getPaytype() == 1 && (sellform.getPartitionflag() == 3 || sellform.getPartitionflag() == 4)) {
//            whoutformService.childWhoutSettleFinalAmount(sellform, false);
            this.childWhoutSettleFinalAmount(sellform, false);
        }
        //反向出库
        //20230918 新增Whoutform参数 zhangfu
        ArrayList<Whoutform> wof = new ArrayList<>();
//        whoutformService.whinoutBack(sysUser, sellform.getGuid(), 2,wof);

        //处理销售单明细中的出库数量
        Sellitem si = new Sellitem();
        si.setSellguid(sellform.getGuid());
        List<Sellitem> sis = sellitemMapper.selectSellitemList(si);
        for (Sellitem s : sis) {
            s.setLoadweight(BigDecimal.ZERO);
            s.setUpdateBy(sysUser.getUserId());
            s.setUpdateTime(DateUtils.getNowDate());
            sellitemMapper.updateSellitem(s);
        }

        Date backDatedDate;
        if (null == sellform.getPlantformLoadDate()) {
            backDatedDate = DateUtils.getNowDate();
        } else {
            String overDate = sysConfigService.selectConfigByKey("over_date");
            backDatedDate = MeituanDataProcessUtil.getLoadingTime(sellform.getPlantformLoadDate(), null, 2, Integer.parseInt(overDate));
        }
        whoutformService.whoutBack(sellform.getGuid(), backDatedDate, wof);

        sellform.setPlatformId(sellform.getStrmId());
        sellform.setCode(sellform.getSellcode());

        //2023-05-15 销售订单反出库时，检查：
        //1、1如果当前订单核销状态为未核销，直接删除当前订单的待核销队列
        //2、3如果当前订单核销状态为已核销，则冲回已核销数据（将客户预收款余额冲回），并修改当前订单核销状态为未核销
//        if (1 == sellform.getMoneybackStatus()) {
        if (3 != sellform.getMoneybackStatus()) {
            SfPrebalanceRecord endRecord3 = sfPrebalanceRecordMapper.selectHeXiaoRecordStatus3(id);
            if (null != endRecord3) {
                endRecord3.setStatus(0);
                sfPrebalanceRecordMapper.updateSfPrebalanceRecord(endRecord3);
            }
            //20231010,以当前订单结算金额生成一笔反向的应收账款流水即可
            generateRecievableBalance(sellform, 2);
        }
        if (3 == sellform.getMoneybackStatus()) {
            SfPrebalanceRecord endRecord = sfPrebalanceRecordMapper.selectHeXiaoRecord(id);
            if (null != endRecord) {
                prebalanceRecordService.hexiaoReverse(endRecord);
            }
            SfPrebalanceRecord endRecord2 = sfPrebalanceRecordMapper.selectHeXiaoRecordStatus2(id);
            if (null != endRecord2) {
                prebalanceRecordService.hexiaoReverse(endRecord2);
            }
        }

        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, sellform
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Sellform sf = new Sellform();
            sf.setStatus(result.getNextStat());
            sf.setGuid(sellform.getGuid());
            this.updateSellform(sf);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult settle(Long id, String fileIds, String opinion, Long taskid, Sellform sellform) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (id == null) {
            id = sellform.getId();
        }
        //20240110 改造，为了避免反复读取、更新sellform、sellitem
        //读取sellform，将前台传送的backFlag：是否退回库房标志，流程用，赋值给sellform
//        newSellform.setId(id);
        Sellform newSellform = selectSellformById(id);
        newSellform.setBackFlag(sellform.getBackFlag());
        newSellform.setItems(new ArrayList<>());
//        sellformMapper.updateSellform(newSellform);

        //0110 Sellform sf = sellformMapper.selectSellformById(id);

        if (0 == sellform.getBackFlag()) {
//        //TODO 20230905 更新销售订单明细单价
            boolean settle = false;
            boolean settlePriceChanged = false;
            for (Sellitem item : sellform.getItems()) {
                //20240110 前台送上来的销售订单明细数据，其中有变化之后的价格
                Sellitem newSellformItem = sellitemMapper.selectSellitemById(item.getGuid());
                if (newSellformItem.getPrice().compareTo(item.getPrice()) != 0) {
                    settle = true;
                }
                if (newSellformItem.getPrice().compareTo(item.getPrice()) == 1) {
                    settlePriceChanged = true;
                }
                newSellformItem.setPrice(item.getPrice());
                newSellform.getItems().add(newSellformItem);
                //0110 Sellitem sellitem = new Sellitem();
                //0110 sellitem.setGuid(item.getGuid());
                //0110 sellitem.setPrice(item.getPrice());
                //0110 sellitemMapper.updateSellitem(sellitem);
            }

            if (settle) {
                //20231010 首先保存之前的结算金额
                BigDecimal beforeSettleAmount = newSellform.getFinalamount();
                //结算
                //0110 settleOne(sellform.getFinalamount(), user, sf);
                if (settlePriceChanged) {
                    newSellform.setSettlePriceChanged(1);
                }
                newSettle(newSellform);
                //20231010 以新的结算金额，重新计算应付账款
                regenerateRecableBalance(newSellform, beforeSettleAmount);
                //判断单价是否发生变化，变化则冲回原出库单、重新按照新的单价生成出库单
                reGenerateWhoutForPayAfter(newSellform, user);
            }

            //20231017 结算确认节点生成核销记录
            if (availableRecbalance(newSellform, 1)) {
                settleHexiao(newSellform, user);
            }
        }


//        sf.setPlatformId(sf.getStrmId());
//        sf.setCode(sf.getSellcode());

        //统一更新，sellitem
        for (Sellitem item : newSellform.getItems()) {
            item.setUpdateBy(user.getUserId());
            sellitemService.updateSellitem(item);
        }
        //发起流程之前更新sellform
        this.updateSellform(newSellform);
        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, newSellform
                , user);
        Sellform sf1 = new Sellform();
        sf1.setSettletime(new Date());
        sf1.setStatus(result.getNextStat());
        sf1.setId(id);
        this.updateSellform(sf1);

        return AjaxResult.success();

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult recharge(Long id, String fileIds, String opinion, Long taskid, Sellform sellform) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (id == null) {
            id = sellform.getId();
        }
        Sellform sf = sellformMapper.selectSellformById(id);
        //TODO 20230905上车付款的结算确认节点修改为充值节点
        // 货到付款的充值功能：同上车付款的充值
        if (StringUtils.equalsIgnoreCase("36", sf.getFlowtempguid()) && (sf.getPaytype() == 2)) {
            Recharge recharge = new Recharge();
            recharge.setCustomerid(sf.getCustomerguid());
            recharge.setCustomer(sf.getCustomername());
            recharge.setType(1);
            recharge.setAmount(sellform.getAmount() == null ? BigDecimal.ZERO : sellform.getAmount());
            recharge.setDepartid(sf.getDepguid());
            recharge.setDeptId(sf.getDeptId());
            recharge.setDepartname(sf.getDepname());
            recharge.setSellformId(sf.getId());
            recharge.setSellformCode(sf.getSellcode());
            recharge.setRemark(opinion);
            String newFileIds = "";
            if (StringUtils.isNotBlank(fileIds)) {
                String[] ids = fileIds.split(",");
                Long[] idss = (Long[]) ((Long[]) ConvertUtils.convert(ids, Long.class));
                Long[] var8 = idss;
                int var9 = idss.length;

                for (int var10 = 0; var10 < var9; ++var10) {
                    FileInfo info = fileInfoMapper.selectFileInfoById(var8[var10]);
                    this.fileInfoMapper.insertFileInfo(info);
                    newFileIds = newFileIds + "," + info.getId();
                }
            }
            rechargeService.save(recharge, sf.getDeptId(), newFileIds, null, opinion);

            sf.setRechargeId(recharge.getId());
            sf.setRechargeCode(recharge.getCode());
            sellformMapper.updateSellform(sf);
        }
        //结算
//        settleOne(sellform.getFinalamount(), user, sf);

        sf.setPlatformId(sf.getStrmId());
        sf.setCode(sf.getSellcode());
        FlowResult result = flowProcessProxy.approval(taskid, fileIds, opinion, sf
                , user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Sellform sf1 = new Sellform();
            sf1.setSettletime(new Date());
            sf1.setStatus(result.getNextStat());
            sf1.setId(id);
            this.updateSellform(sf1);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    /**
     * 当前订单的出库日期是否大于系统设定的启用日期，大于启用日期才开始：
     *
     * @param sellform
     * @param type     1 - 生成核销队列  2 - 生成应收账款 3 - 核销
     * @return
     */
    public boolean availableRecbalance(Sellform sellform, int type) {
        //样品订单不生成
        if ("35".equals(sellform.getFlowtempguid())) {
            return false;
        }
        boolean online = !BatchStatus.batchRunning();
        if (sellform.getPaytype() == 2 && (type == 1 || type == 3) && online) {
            //上车付款的,允许联机交易生成核销队列，也允许核销
            return true;
        }

        //上车付款或货到付款的，当前日期大于启用日期的，启用应收账款
        if ((sellform.getPaytype() == 2) || sellform.getPaytype() == 3) {
            String startDate = this.sysConfigService.selectConfigByKey("hexiao_date_start");
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date startDateD;
            try {
                startDateD = format.parse(startDate);
            } catch (Exception e) {
                throw new CustomException("日期计算错误 in sellformServiceImpl");
            }
            return DateUtils.compare(sellform.getLoadDate(), startDateD);
        }
        //其他订单，直接启用应收账款
        return true;
    }

    /**
     * 生成当前销售订单的应收账款记录,销售订单出库节点调用
     *
     * @param sellform
     * @param type     1 - 正向交易 2- 反向
     */
    @Transactional
    public void generateRecievableBalance(Sellform sellform, Integer type) {
        //全额预付的、样品、赠送的销售订单，暂不做应收账款的处理
        if (sellform.getPaytype() == 1 || sellform.getPaytype() == 4 || sellform.getPaytype() == 5) {
            return;
        }
        //上车付款、货到付款，某一时间点之后开始处理应收账款
        if (!availableRecbalance(sellform, 2)) {
            return;
        }

        Customer cust = customerMapper.selectCustomerById(sellform.getCustomerguid());
        String remark = type == 1 ? "订单出库生成应收款" : "订单反出库冲回应收账款";
        receivableflowService.saveRecableLogs(cust, sellform, null, type, "Sellform", sellform.getId(), sellform.getSellcode(), remark);
        customerMapper.updateCustomer(cust);
    }

    @Transactional
    public void regenerateRecableBalance(Sellform sellform, BigDecimal b4SettleAmount) {
        //全额预付的、样品、赠送的销售订单，暂不做应收账款的处理
        if (sellform.getPaytype() == 1 || sellform.getPaytype() == 4 || sellform.getPaytype() == 5) {
            return;
        }
        //上车付款、货到付款，某一时间点之后开始处理应收账款
        if (!availableRecbalance(sellform, 2)) {
            return;
        }
        Customer cust = customerMapper.selectCustomerById(sellform.getCustomerguid());
        if (3 != sellform.getMoneybackStatus()) {
            //销售订单尚未核销，生成反向，然后再生成正向即可

            receivableflowService.saveRecableLogs(cust, sellform, b4SettleAmount, 2, "Sellform", sellform.getId(), sellform.getSellcode(), "结算确认冲回");

            receivableflowService.saveRecableLogs(cust, sellform, null, 1, "Sellform", sellform.getId(), sellform.getSellcode(), "结算确认重新生成");

            customerMapper.updateCustomer(cust);
            return;
        }

        //否则，销售订单已被核销，冲回核销记录，余额返还客户
        SfPrebalanceRecord endRecord = sfPrebalanceRecordMapper.selectHeXiaoRecord(sellform.getId());
        if (null != endRecord) {
            prebalanceRecordService.hexiaoReverse(endRecord);
        }
        //以结算确认后的金额生成应收账款数据
        receivableflowService.saveRecableLogs(cust, sellform, null, 1, "Sellform", sellform.getId(), sellform.getSellcode(), "结算确认重新生成");
        customerMapper.updateCustomer(cust);

        return;
    }

    public void settleHexiao(Sellform sellform, SysUser user) {
        if (sellform.getPaytype() == 4 || sellform.getPaytype() == 5) {
            return;
        }
        SfPrebalanceRecord prebalanceRecord = new SfPrebalanceRecord();
        prebalanceRecord.setSellformId(sellform.getId());
        prebalanceRecord.setStats(new Integer[]{1, 2});
        prebalanceRecord.setType(1);
        List<SfPrebalanceRecord> records = sfPrebalanceRecordMapper.selectSfPrebalanceRecordList(prebalanceRecord);
        if (records.size() > 0) {
            for (int i = 0; i < records.size(); i++) {
                sfPrebalanceRecordMapper.deleteSfPrebalanceRecordById(records.get(i).getId());
            }
        }
        prebalanceRecordService.createPrebalanceRecord(sellform.getId(), sellform.getSellcode(), sellform.getFinalamount(), user, 1);
    }

    @Transactional
    public void settleOne(BigDecimal finalamount, SysUser user, Sellform sf) {
//        Sellitem sellitem = new Sellitem();
//        sellitem.setSellguid(sf.getGuid());
//        List<Sellitem> items = sellitemMapper.selectSellitemList(sellitem);
        List<Sellitem> items = sellitemMapper.selectSellitemListOuted(sf.getGuid());
        // 更新明细中的结算信息
        BigDecimal settleweight = new BigDecimal(0);// 结算重量
        BigDecimal amount = new BigDecimal(0);// 扣前金额
        for (Sellitem item : items) {
            item.setUnloadweight(item.getLoadweight());
            item.setSettleweight(item.getLoadweight()
                    .subtract(new BigDecimal(item.getLoadhandsel() == null ? 0 : item.getLoadhandsel())));
            settleweight = settleweight.add(item.getSettleweight());// 结算重量等于发货重量-赠送
            BigDecimal settleamount = item.getPrice().multiply(item.getSettleweight()).setScale(2, BigDecimal.ROUND_HALF_UP);
            amount = amount.add(settleamount);
            // 结算金额
            item.setSettleamount(settleamount);
            item.setUpdateBy(user.getUserId());
            item.setUpdateTime(DateUtils.getNowDate());

            sellitemMapper.updateSellitem(item);
        }
        // 更新应收账款
        //20231010 按照新的业务逻辑更新应收账款，所以，不需要读取客户信息了，下面一行备注...
//        Customer cust = customerMapper.selectCustomerById(sf.getCustomerguid());

        sf.setFinalamount(amount);
        if (finalamount == null || BigDecimal.ZERO.compareTo(finalamount) == 0) {
            sf.setFinalamount(amount);
            sf.setMaxdeduct(BigDecimal.ZERO);
        } else {
            sf.setFinalamount(finalamount);
            if (sf.getAmount().compareTo(finalamount) != 0) {
                discountMapper.deleteDiscountByOrderguid(sf.getGuid());
                //计算折扣率
                BigDecimal discount = (sf.getAmount().subtract(finalamount)).divide(sf.getAmount(), 4, BigDecimal.ROUND_HALF_UP);
                sf.setMaxdeduct(discount);

                Discount dist = new Discount();
                dist.setOrdercode(sf.getSellcode());
                dist.setOrderguid(sf.getGuid());
                dist.setCustomerid(sf.getCustomerguid());
                dist.setCustomer(sf.getCustomername());
                dist.setAmount(sf.getAmount());
                dist.setFinalamount(sf.getFinalamount());
                dist.setDifferamount(sf.getAmount().subtract(finalamount));
                dist.setDiscount(discount);
                dist.setSalesman(sf.getApplyname());
                dist.setSalesmanid(sf.getOperatorid());
                discountMapper.insertDiscount(dist);
            } else {
                sf.setMaxdeduct(BigDecimal.ZERO);
            }
        }


        if (null != sf.getWithdrawtype()) {
            if (4 == sf.getWithdrawtype()) {
                sf.setFinalamount(sf.getFinalamount().subtract(
                        sf.getDeductamount() == null ? BigDecimal.ZERO : sf.getDeductamount()));
            }
        }

        //判断下单金额 > 结算金额 * 参数,则设置SettlePriceChanged=1
        String proess = sysConfigService.selectConfigByKey("settlePrice_float_allowed");
        if (sf.getAmount().compareTo(sf.getFinalamount().multiply(BigDecimal.valueOf(Long.parseLong(proess)))) > 0) {
            sf.setSettlePriceChanged(1);
        }
        sellformMapper.updateSellform(sf);

        // 更新应收账款流水
        //20231010 停掉以前的应收账款流水操作
//        receivableflowService.saveRecableLogs(cust, sf, sf.getFinalamount(), user, 1);
    }

    /**
     * 销售订单新结算方法，由于退款补货、折扣等业务逻辑都已不存在了，所以，按照现有逻辑进行结算
     * 出库环节的结算，直接按照销售订单的单价、出库数量结算
     * 结算确认环节的结算，按照前端送上来的结算单价进行重新结算
     * 销售下单的时候，明细表中的settleamount=null，主表中的amount=finalamount=sum(下单数量*单价)
     * 出库的时候，调用此方法，计算明细表settleAmount = 出库数量 * 下单单价
     * 主表的finalamount = sum(明细表settleAmount）
     * 结算确认的时候，按照结算单价重新计算finalamount = 出库数量 * 新单价
     *
     * @param sellform 销售订单详情信息，包含sellitem数据
     */
    @Transactional
    public void newSettle(Sellform sellform) {

        List<Sellitem> items = sellform.getItems();
        // 更新明细中的结算信息
        BigDecimal settleweight = new BigDecimal(0);// 结算重量
        BigDecimal amount = new BigDecimal(0);// 扣前金额
        for (Sellitem item : items) {
            if (item.getLoadweight() == null || BigDecimal.ZERO.compareTo(item.getLoadweight()) == 0) {
                continue;
            }
            item.setUnloadweight(item.getLoadweight());
            item.setSettleweight(item.getLoadweight()
                    .subtract(new BigDecimal(item.getLoadhandsel() == null ? 0 : item.getLoadhandsel())));
            settleweight = settleweight.add(item.getSettleweight());// 结算重量等于发货重量-赠送
            BigDecimal settleamount = item.getPrice().multiply(item.getSettleweight()).setScale(2, BigDecimal.ROUND_HALF_UP);
            amount = amount.add(settleamount);
            // 结算金额
            item.setSettleamount(settleamount);
            //sellitemMapper.updateSellitem(item);
        }

        sellform.setFinalamount(amount);
        sellform.setMaxdeduct(BigDecimal.ZERO);

        //判断下单金额 > 结算金额 * 参数,则设置SettlePriceChanged=1
        /*String proess = sysConfigService.selectConfigByKey("settlePrice_float_allowed");
        if (sellform.getAmount().compareTo(sellform.getFinalamount().multiply(BigDecimal.valueOf(Long.parseLong(proess)))) > 0) {
            sellform.setSettlePriceChanged(1);
        }*/
        //sellformMapper.updateSellform(sellform);

    }

    /**
     * “货到付款”的销售订单，结算确认节点用户录入结算金额后，系统计算结算单价写入到新增的settle_price中。
     * 系统设置参数settlePrice_float_allowed字段，
     * 系统判断销售订单明细如果满足settle_price > price*settlePrice_float_allowed，则更新主表settlePrice_changed=1。
     *
     * @param sf
     * @param user
     */
    @Transactional
    public void reGenerateWhoutForPayAfter(Sellform sf, SysUser user) {
        //
//        String proess = sysConfigService.selectConfigByKey("settlePrice_float_allowed");
        if (StringUtils.equalsIgnoreCase("36", sf.getFlowtempguid()) && sf.getPaytype() == 3) {
            //录入的结算金额和系统结算的结算金额有差异
            if (sf.getAmount().compareTo(sf.getFinalamount()) != 0) {
                //反出库，按照结算单价出库
                //20230918 新增Whoutform参数 zhangfu
                ArrayList<Whoutform> wofList = new ArrayList<Whoutform>();

//                whoutformService.whinoutBack(user, sf.getGuid(), 2,wofList);
                //20240110 调用新的反出库逻辑
                whoutBackAfterSettle(user, sf, wofList);
                //用新的单价生成新的入库单
                //0110 Sellform sellform = new Sellform();
                //0110 sellform.setId(sf.getId());
                //0110 sellform = sellformMapper.findDetail(sellform);
                //0110 whoutformService.generateNewWhoutform(wofList,sellform);
                generateNewWhoutform(wofList, sf);
            }
        }

    }


    /**
     * 结算确认后如果单价发生变化，原出库单反出库 20240110 按照新的反出库逻辑处理
     *
     * @param user          当前用户
     * @param sellform      销售订单
     * @param whoutformList 反出库操作后生成的新的出库单
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void whoutBackAfterSettle(SysUser user, Sellform sellform, List<Whoutform> whoutformList) {
        //处理销售单明细中的出库数量
        Sellitem si = new Sellitem();
        si.setSellguid(sellform.getGuid());
        List<Sellitem> sis = sellitemMapper.selectSellitemList(si);
        for (Sellitem s : sis) {
            s.setLoadweight(BigDecimal.ZERO);
            s.setUpdateBy(user.getUserId());
            s.setUpdateTime(DateUtils.getNowDate());
            sellitemMapper.updateSellitem(s);
        }

        Date backDatedDate;
        if (null == sellform.getPlantformLoadDate()) {
            backDatedDate = DateUtils.getNowDate();
        } else {
            String overDate = sysConfigService.selectConfigByKey("over_date");
            backDatedDate = MeituanDataProcessUtil.getLoadingTime(sellform.getPlantformLoadDate(), null, 2, Integer.parseInt(overDate));
        }
        whoutformService.whoutBack(sellform.getGuid(), backDatedDate, whoutformList);
    }

    /**
     * 销售订单结算后，如果结算金额发生了变化，反出库之后的重新出库操作
     *
     * @param whoutforms 反出库生成的反出库单局
     * @param sellform   销售订单、包括明细表
     *                   2024-01-10
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void generateNewWhoutform(ArrayList<Whoutform> whoutforms, Sellform sellform) {
        //目前暂时不存在一条业务数据在一次出库的时候产生多条出库单的情况，所以只处理第一条
        Whoutform wof = whoutforms.get(0);
        List<Whoutformitem> whoutformitems = wof.getItems();
        List<Sellitem> sellitems = sellform.getItems();

        wof.setAutoid(null);

        wof.setRemark("系统自动重新生成出库单！");
        wof.setWeight(BigDecimal.ZERO);
        for (Whoutformitem item : whoutformitems) {
            for (int i = 0; i < sellitems.size(); i++) {
                Sellitem sellitem = sellitems.get(i);
                if (item.getItemguid().equals(sellitem.getGuid())) {
                    item.setPrice(sellitem.getPrice());
                    break;
                }
            }
            item.setWeight(item.getWeight().negate());
        }
        whoutformService.whout(wof, whoutformitems, false, null);
    }

    @Override
    public AjaxResult getSettlementInfo(Long id) {
        Sellform sf = sellformMapper.selectSellformById(id);

        Sellitem it = new Sellitem();
        it.setSellguid(sf.getGuid());
        List<Sellitem> items = sellitemMapper.getSellItems(it);


        BigDecimal finalAmount = BigDecimal.ZERO;// 优惠后
        BigDecimal finalweight = BigDecimal.ZERO;// 结算重量
        BigDecimal handselweight = BigDecimal.ZERO;// 赠送重数

        for (Sellitem si : items) {
            if (si.getLoadweight() != null) {
                si.setUnloadweight(si.getLoadweight());// 暂时把卸车重量等于装车重量
                // 结算重量
                BigDecimal setlweight = BigDecimal.ZERO;
                setlweight = si.getLoadweight()
                        .subtract(new BigDecimal(si.getLoadhandsel() == null ? 0 : si.getLoadhandsel()));
                // 计算总的赠送重量
                handselweight = handselweight
                        .add(new BigDecimal(si.getLoadhandsel() == null ? 0 : si.getLoadhandsel()));
                // 结算金额
                BigDecimal settlamount = si.getPrice().multiply(setlweight).setScale(2,
                        BigDecimal.ROUND_HALF_UP);

                finalAmount = finalAmount.add(settlamount);

                si.setSettleamount(settlamount);
                si.setSettleweight(setlweight);
                // 结算数量
                finalweight = finalweight.add(setlweight);
            }
        }

        /**
         * 套装明细处理
         */
        Sellspitem spitem = new Sellspitem();
        spitem.setSellguid(sf.getGuid());
        System.out.println("________confirm  setl___");
        List<Sellspitem> spitems = sellspitemMapper.findAboutSellitems(spitem);
        System.out.println("________confirm  setl___");
        for (Sellspitem si : spitems) {
            if (si.getLoadcount() != null) {
                si.setUnloadcount(si.getLoadcount());// 暂时把卸车件数等于装车件数
                // 结算件数
                int setlcount = 0;
                setlcount = si.getLoadcount() - (si.getLoadhandsel() == null ? 0 : si.getLoadhandsel());
                // 结算金额
                BigDecimal settlamount = si.getPrice().multiply(new BigDecimal(setlcount)).setScale(2,
                        BigDecimal.ROUND_HALF_UP);
                finalAmount = finalAmount.add(settlamount);
                si.setSettleamount(settlamount);
                si.setSettlecount(setlcount);
                sellspitemMapper.updateSellspitem(si);
            }
        }

        if (null != sf.getDeductamount()) {
            sf.setFinalamount(finalAmount.subtract(sf.getDeductamount()));
        } else {
            sf.setFinalamount(finalAmount);
        }
        sf.setAmount(finalAmount);
        sf.setItems(items);

        ArrayList<Sellitem> reItems = new ArrayList<>();
        for (int i = 0; i < sf.getItems().size(); i++) {
            Sellitem item = sf.getItems().get(i);
            String suitpackid = item.getSuitpackid();
            if (StringUtils.isNotBlank(suitpackid)) {
                reItems.add(item);
            }
        }
        sf.getItems().removeAll(reItems);
        return AjaxResult.success(sf);
    }

    @Override
    public boolean callbackAfterRefuseToStart(CallBackParameterWrapper cbpw) {
        //202306123预收款判断处理: 子订单删除时，计算子订单结算金额 =订单单价*订单数量， 更新主订单finalamount = finalamount + 结算金额。
        log.info(">>>>>>>>>>> sellform callbackAfterRefuseToStart start");
        Sellform sellform = new Sellform();
        sellform.setId(cbpw.getBase().getId());
        sellform = sellformMapper.findDetail(sellform);

        if (sellform.getPaytype() == 1 && (sellform.getPartitionflag() == 3 || sellform.getPartitionflag() == 4)) {
            Sellform sellformParent = sellformMapper.selectSellformByGuid(sellform.getParentguid());
            List<Sellitem> pitems = sellform.getItems();
            List<Sellspitem> spitems = sellform.getSpitems();
            //结算金额2=订单单价*订单数量
            BigDecimal curr_Order_Amt = new BigDecimal(0);
            for (Sellitem b : pitems) {
                if (StringUtils.isBlank(b.getSuitpackid())) {
                    curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply((b.getWeight())));
                }
            }
            if (spitems.size() > 0) {
                for (Sellspitem b : spitems) {
                    curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())));
                }
            }
            if (null != sellformParent.getFinalamount()) {
                Sellform sf = new Sellform();
                sf.setGuid(sellform.getParentguid());
                sf.setFinalamount(sellformParent.getFinalamount().add(curr_Order_Amt));
                sellformMapper.updateSellform(sf);
            }
        }
        log.info("sellform callbackAfterRefuseToStart end <<<<<<<<<<<<<");

        return true;
    }

    //TODO 2023.09.05增加一个回调方法，自动完成出库，回调方法可配置在财务审批节点完成之后
    @Transactional
//    @Override
    public boolean callback(CallBackParameterWrapper cbpw) {
        log.info(">>>>>>>>>>> sellform callback start");
        Sellform sellform = new Sellform();
        sellform.setId(cbpw.getBase().getId());
        sellform = sellformMapper.findDetail(sellform);

        if (sellform.getAutoType() == 2) {

            FlowTempNode node = new FlowTempNode();
            node.setOrderId(sellform.getId());
//            node.setCreateBy(1L);
            node.setFlowId(Long.valueOf(sellform.getFlowtempguid()));
            List<FlowTempNode> nodes = iFlowtempnodeService.getPendingNodes(node);
            Whoutform entity = new Whoutform();
            List<Whoutformitem> items = new ArrayList<>();
            List<Sellitem> sellitems = sellform.getItems();
            for (int i = 0; i < sellitems.size(); i++) {
                Sellitem sellitem = sellitems.get(i);
                Whoutformitem whoutformitem = new Whoutformitem();
                whoutformitem.setSrguid(sellform.getStorermguid());
                Storehouseroom room = new Storehouseroom();
                room.setStoreguid(sellform.getStorermguid());
                room.setShrtype(1);
                //20230919 自动入库库间的选取，通过auto_tranfer获取

                AutoTransfer cond = new AutoTransfer();
                cond.setToOrguid(sellform.getStorerOrgguid());
                cond.setToStrmguid(sellform.getStorermguid());
                AutoTransfer autoTransfer = autoTransferService.findAutoTransfer(cond);
                if (autoTransfer == null) {
                    room = storehouseroomMapper.selectSHbySotreIdAndType(room);
                } else {
                    room = storehouseroomMapper.selectStorehouseroomById(autoTransfer.getToShguid());
                }

                if (room == null) {
                    throw new CustomException("没有找到入库库间！");
                }
                whoutformitem.setShrguid(room.getGuid());
                whoutformitem.setProductguid(sellitem.getProductguid());
                whoutformitem.setProduct(sellitem.getProductname());
                whoutformitem.setSpguid(sellitem.getSpguid());
                whoutformitem.setSpename(sellitem.getSpname());
//                whoutformitem.setStockunitid(sellitem.getSfunitid());
                whoutformitem.setWeight(sellitem.getWeight());
                whoutformitem.setSfunitid(sellitem.getSfunitid());
                whoutformitem.setItemguid(sellitem.getGuid());
                whoutformitem.setPrice(sellitem.getPrice());
                items.add(whoutformitem);
            }
            entity.setItems(items);
            //20240112
//            whoutformService.saveWhoutFormAndImg(sellform.getId(), entity, null, "系统自动完成", nodes.get(0).getFlowTaskId(), "2");
            this.whout(sellform.getId(), entity, null, "系统自动完成", nodes.get(0).getFlowTaskId(), null);
        }
        log.info("sellform callback end <<<<<<<<<<<<<");

        return true;
    }

    //TODO 2023.09.07“货到付款”的销售订单，在“赊销审批”节点完成后新增回调任务：
    @Transactional
//    @Override
    public boolean callbackSX(CallBackParameterWrapper cbpw) {
        log.info(">>>>>>>>>>> sellform callbackSX start");
        log.info(">>>>>>>>>>> callbackCount: " + cbpw.getCallbackCount());
        if (cbpw.getCallbackCount() > 1) {
            return true;
        }
        Sellform sellform = new Sellform();
        sellform.setId(cbpw.getBase().getId());
        sellform = sellformMapper.findDetail(sellform);

        if (sellform.getAutoType() != 2 || sellform.getLinkedId() == null) {
            return true;
        }
        if (sellform.getPaytype() != 3) {
            return true;
        }

        processFreightorder(sellform);
        log.info("sellform callbackSX end <<<<<<<<<<<<<");

        return true;
    }

    /**
     * 回调处理采收订单，完成“等待销售订单处理”节点，并完成自动入库
     *
     * @param sellform
     */
    @Transactional
    public void processFreightorder(Sellform sellform) {
        Freightorder freightorder = new Freightorder();
        freightorder.setId(sellform.getLinkedId());
        freightorder.setPaystatus(2);
        freightorderService.updateFreightorder(freightorder);

        //获取对应采收订单的待处理任务
        FlowTempNode node = new FlowTempNode();
        node.setOrderId(sellform.getLinkedId());
        node.setFlowId(40l);
        List<FlowTempNode> nodes = iFlowtempnodeService.getPendingNodes(node);

        freightorderService.approval(sellform.getLinkedId(), nodes.get(0).getFlowTaskId(), null, null);
        freightorderService.whinAuto(sellform.getLinkedId(), freightorder.getWeight());
    }

    //TODO 2023.09.07“上车付款”的销售订单，新增流程结束回调：
    @Transactional
    @Override
    public boolean callbackAfterFinish(CallBackParameterWrapper cbpw) {
        log.info(">>>>>>>>>>> sellform callbackAfterFinish start");
        log.info(">>>>>>>>>>> callbackCount: " + cbpw.getCallbackCount());
        if (cbpw.getCallbackCount() > 1) {
            return true;
        }
        Sellform sellform = new Sellform();
        sellform.setId(cbpw.getBase().getId());
        sellform = sellformMapper.findDetail(sellform);

        if (sellform.getPaytype() == 2 && sellform.getAutoType() == 2) {
            processFreightorder(sellform);
        }

        log.info("sellform callbackAfterFinish end <<<<<<<<<<<<<");
        return true;
    }

    @Override
    public int updateBaseStatus(Long id, Integer status) {
        Sellform sellform = new Sellform();
        sellform.setId(id);
        sellform.setStatus(status);
        sellformMapper.updateSellform(sellform);
        return IFlowBaseService.super.updateBaseStatus(id, status);
    }

    @Override
    public BasePojo getBaseById(Long id) {
        return selectSellformById(id);
    }

    @Override
    public BasePojo getBaseByCode(String code) {
        return selectSellformByCode(code);
    }

    /**
     * 20240104     销售订单出库操作
     *
     * @param id        销售订单Id
     * @param whoutform 出库单实体，前端传入，包含出库明细信息
     * @param fileIds   上传的附件Ids
     * @param opinion   出库审批意见
     * @param taskid    销售订单待处理任务Id，前端传入
     * @param opttype   销售出库类型，=2，前端传入，实际不需要传入
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whout(Long id, Whoutform whoutform, String fileIds, String opinion, Long taskid, String opttype) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        List<Whoutformitem> whoutItems = whoutform.getItems();
        whoutform.setIsCopytoKD(1);
        String orderid = "";
        BigDecimal weight = new BigDecimal(0);// 净重


        //获取销售订单
        Sellform sf = selectSellformById(id);
        orderid = sf.getGuid();
        //销售订单的结算方式 1 - 按件数 2-按重量 这个参数需要重新考虑
        int settletype = sf.getSettletype();
        //校验，计算重量
        int loadcount = 0;

        Sellitem sellitem = new Sellitem();
        sellitem.setSellguid(sf.getGuid());
        List<Sellitem> sellitemList = sellitemMapper.selectSellitemList(sellitem);
        sf.setItems(sellitemList);

        Sellspitem sellspitem = new Sellspitem();
        sellspitem.setSellguid(sf.getGuid());
        List<Sellspitem> sellspitemList = sellspitemMapper.selectSellspitemList(sellspitem);
        sf.setSpitems(sellspitemList);

        for (Whoutformitem item : whoutItems) {
            if (1 == settletype) {
                //按件数的销售订单，出库明细中的物料数量为件数，赋值给loadcount
                item.setLoadcount(item.getWeight().intValue());
                loadcount = loadcount + item.getLoadcount();
                calculateHandsel(item, item.getLoadcount());
            }
        }

        //更新销售明细出库重量与数量（出库之前进行，出库后whoutitem中的weight就转换为库存单位了）
        //包括出库数量loadWeight和赠送数量Loadhandsel、以及套装数据
        List<Sellspitem> spitems = updateSellitems(whoutItems, sf);

        //出库单主表数据准备
        setDataPrepared(whoutform, sf);

        //出库，调用whoutformService的出库方法统一完成出库
        //外部渠道，或者采收地头直销发起的，允许负库存
        boolean minusAllowed = sf.getAutoType() == 2 || whoutform.isExternalChannel();
        String overDate = sysConfigService.selectConfigByKey("over_date");
        Date outTime = MeituanDataProcessUtil.getLoadingTime(sf.getPlantformLoadDate(), null, 2, Integer.parseInt(overDate));

        weight = whoutformService.whout(whoutform, whoutItems, minusAllowed, outTime);

        //202306123预收款判断处理 分拆子订单出库后更新父订单的结算金额
        if (sf.getPaytype() == 1 && (sf.getPartitionflag() == 3 || sf.getPartitionflag() == 4)) {
            childWhoutSettleFinalAmount(sf, true);
        }

        //更新销售订单主表数据
        updateSellform(whoutform, weight, loadcount, sf, spitems);


        /* *
         * 2020-07-21 出库后 更新物流单 装车状态
         **/
        updateWlStatus(orderid, sysUser);


        //settleOne方法中的更新sellform应该去掉，待查
        //settleOne(null, sysUser, sf);
        newSettle(sf);
//            if (sellform.getPaytype() == 1){//全额预付，就在出库节点做核销处理，否则就在结算确认节点做
        //2023-10-16 按件数的，需要在出库的时候生成核销队列
        //2023-10-18 上车付款的，出库节点不再生成核销队列，充值完成后的回调节点处理
//            if (StringUtils.equalsIgnoreCase("36", sellform.getFlowtempguid()) &&
        if (availableRecbalance(sf, 1)
                && (sf.getSettletype() == 1)
                && sf.getPaytype() != 2) {
            settleHexiao(sf, sysUser);
        }

        //20231010 形成针对非全额预付的、非样品订单，生成应收账款记录
        generateRecievableBalance(sf, 1);

        //统一更新销售订单明细数据
        for (Sellitem item : sf.getItems()) {
            item.setUpdateBy(sysUser.getUserId());
            sellitemService.updateSellitem(item);
        }
        //最后发起审批
        //审批之前更新sellform，流程处理中条件流程可能要用到
        updateSellform(sf);
        FlowResult flowResult = flowProcessProxy.approval(taskid, fileIds, opinion, sf
                , sysUser);
        //更新销售订单 ,只更新sellform状态
        Sellform sellform = new Sellform();
        sellform.setId(sf.getId());
        sellform.setStatus(flowResult.getNextStat());
        updateSellform(sellform);
        return AjaxResult.success();

    }

    /**
     * 20240105 更新物流订单状态
     *
     * @param orderid
     * @param sysUser
     */
    private void updateWlStatus(String orderid, SysUser sysUser) {
//        Wlinfoitem wlitem = wlinfoitemMapper.selectWlinfoitemByOrderId(orderid);
//        if (wlitem != null) {
//            // 单一订单
//            if (wlitem.getWlstatus().equals("0")) {
//                //handleWlinfo(wlitem, sysUser);
//            } else {
//                // 非单一订单的时候 查询其他订单是否已出库 ，若已出库 则更新物流单装车状态
//                Wlinfoitem item = new Wlinfoitem();
//                item.setWlinfoid(wlitem.getWlinfoid());
//                List<Wlinfoitem> wlitems = wlinfoitemMapper.selectWlinfoitemList(item);
//
//                String[] orderids = new String[wlitems.size()];
//                for (int i = 0; i < wlitems.size(); i++) {
//                }
//
//                List<String> arrList = new ArrayList<>(Arrays.asList(orderids));
//                arrList.remove(arrList.indexOf(orderid));
//                String[] orderidss = arrList.toArray(new String[arrList.size()]);
//
//                Sellform sel = new Sellform();
//                sel.setIds(orderidss);
//                sel.setLtstatus(45);// 未出库
//                List<Sellform> sflist = sellformMapper.selectSellformList(sel);
//                if (sflist.size() < 1) {// 都已出库
//                    //handleWlinfo(wlitem, sysUser);
//                }
//            }
//        }
    }

    /**
     * 20240105 从whoutformServiceImpl中迁移
     * 子订单出库后，更新父订单的结算金额
     *
     * @param sf：子订单
     * @param reverse true:出库 false:反出库
     */
    public void childWhoutSettleFinalAmount(Sellform sf, Boolean reverse) {
        Sellform sellformParent = sellformMapper.selectSellformByGuid(sf.getParentguid());
        if (null != sellformParent.getFinalamount()) {
            List<Sellitem> pitems = sf.getItems();
            List<Sellspitem> spitems = sf.getSpitems();
            //结算金额2=订单单价*订单数量
            BigDecimal curr_Order_Amt = new BigDecimal(0);
            //结算金额2=订单单价*订单数量
            BigDecimal curr_Order_Amt_Out = new BigDecimal(0);
            for (Sellitem b : pitems) {
//                if (StringUtils.isBlank(b.getSuitpackid())) {
                curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply((b.getWeight())));
                curr_Order_Amt_Out = curr_Order_Amt_Out.add(b.getPrice().multiply((b.getLoadweight())
                        .subtract(b.getLoadhandsel() == null ? BigDecimal.ZERO : BigDecimal.valueOf(b.getLoadhandsel()))));
//                }
            }
            //20230110 使用销售订单明细中的单价与金额处理，不使用套装
            /*if (spitems.size() > 0) {
                for (Sellspitem b : spitems) {
                    curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())));
                    curr_Order_Amt_Out = curr_Order_Amt_Out.add(b.getPrice().multiply(new BigDecimal(b.getLoadcount())));
                }
            }*/
            Sellform sellform = new Sellform();
            sellform.setGuid(sf.getParentguid());
            if (reverse) {
                sellform.setFinalamount(sellformParent.getFinalamount().add(curr_Order_Amt).subtract(curr_Order_Amt_Out));
            } else {
                sellform.setFinalamount(sellformParent.getFinalamount().add(curr_Order_Amt_Out).subtract(curr_Order_Amt));
            }
            sellformMapper.updateSellform(sellform);
        }
    }


    /**
     * 20240105从whoutformServiceImpl中迁移
     * 在出库前更新销售订单明细表中的出库数量loadWeight和赠送数量Loadhandsel
     * 结算环节会用到这两个数据。其次，更新套装出库数据
     *
     * @param items
     * @return
     */
    private List<Sellspitem> updateSellitems(List<Whoutformitem> items, Sellform sellform) {
        List<Sellspitem> spitems = sellspitemMapper.selectSellspitemListBySellguid(sellform.getGuid());

        List<Sellitem> sellitemList = sellform.getItems();

        for (Whoutformitem item : items) {
//            sellitemService.updatePI(item, user);
            // 更新套装出库件数
            if (spitems.size() > 0) {
                Sellitem si = sellitemMapper.selectSellitemById(item.getItemguid());
                for (Sellspitem spi : spitems) {
                    if (StringUtils.equalsIgnoreCase(spi.getGuid(), si.getSuitpackid())) {
                        spi.setLoadhandsel(item.getHandsel() == null ? 0 : item.getHandsel().intValue());
                        spi.setLoadcount(item.getLoadcount().intValue());
                        sellspitemMapper.updateSellspitem(spi);
                    }
                }

            }
            //20240110 updatePI的逻辑整合在一起
            //根据出库单明细表定位销售明细数据
            Sellitem sellitem = locateSellitem(sellitemList, item.getItemguid());
            //更新销售订单明细表中的出库数量 loadWeight
            sellitem.setLoadweight(item.getWeight());
            sellitem.setLoadhandsel(item.getHandsel() == null ? 0 : item.getHandsel().intValue());
        }
        return spitems;
    }

    private Sellitem locateSellitem(List<Sellitem> sellitemList, String itemguid) {
        for (Sellitem sellitem : sellitemList) {
            if (sellitem.getGuid().equals(itemguid)) {
                return sellitem;
            }
        }
        throw new CustomException("内部错误，出库数据异常！");
    }

    /**
     * 从whoutformServiceImpl中迁移过来
     *
     * @param entity
     * @param weight
     * @param loadcount
     * @param sf
     * @param spitems
     * @return
     */
    private void updateSellform(Whoutform entity, BigDecimal weight,
                                int loadcount, Sellform sf, List<Sellspitem> spitems) {
        Storeroom room = storeroomMapper.selectStoreroomByGuid(sf.getStorermguid());

        sf.setLoadweight(weight);
        sf.setLbweight(weight);
        sf.setStrmId(room.getId());
        sf.setStrmName(room.getName());
        sf.setStoreOrgId(room.getOrgId());
        sf.setStoreOrgName(room.getOrgname());
        sf.setLoadcount(loadcount);
        // 套装的情况下，出库数量由套装+单品组成
        if (spitems.size() > 0 && entity.getLoadcount() != null) {
            sf.setLoadcount(entity.getLoadcount());
        }
        sf.setPlatformId(sf.getStrmId());
        sf.setCode(sf.getSellcode());

        if (sf.getPaytype() != 3) {
            sf.setSettletime(new Date());
        }
        sf.setLoadDate(new Date());
    }

    /**
     * @return
     * @Author shaodong
     * @Description //销售出库按照订单赠送数量所占订单总数量的比重来计算实际赠送数量
     * @Date 14:58 20240104 方法从whoutformServiceImpl迁移
     * @Param
     **/
    private void calculateHandsel(Whoutformitem item, int loadCount) {
        Sellitem si = sellitemMapper.selectSellitemById(item.getItemguid());
        BigDecimal orderCount = si.getWeight();
        BigDecimal handselcount = new BigDecimal(si.getHandselcount() == null ? 0 : si.getHandselcount());
        if (null != handselcount) {
            BigDecimal handSel = (handselcount.multiply(new BigDecimal(loadCount)).divide(orderCount.add(handselcount), 4, BigDecimal.ROUND_HALF_DOWN)).setScale(0, BigDecimal.ROUND_HALF_EVEN);
            item.setHandsel(handSel);
        }
    }

    /**
     * @return
     * @Author shaodong
     * @Description销售出库添加字段
     * @Date 14:05 20240104 方法从whoutformServiceImpl迁移
     * @Param 数据准备
     **/
    private void setDataPrepared(Whoutform entity, Sellform sf) {
        entity.setDepartmentid(sf.getDepguid());
        //销售出库
        entity.setOuttype(WhoutformTypeEnums.SALE.getCode());
        entity.setOrderguid(sf.getGuid());

        entity.setSrguid(sf.getStorermguid());
        entity.setBusinesscode(sf.getSellcode());
        Organization organization = organizationMapper.selectOrganizationById(sf.getSorgguid());
        entity.setSettlOrgId(sf.getSorgguid());
        entity.setSettlOrgName(organization.getName());
        entity.setRevCustId(sf.getCustomerguid());
        entity.setRevCustName(sf.getCustomername());
        entity.setCurrency(sf.getCurrency());
        entity.setOuttime(new Date());
    }

    public List<Whoutform> getWhoutformAll(String orderGuid) {
        return sellformMapper.getWhoutformAll(orderGuid);
    }
}
